方案
SSDB是一个C/C++语言开发的高性能NoSQL数据库,支持KV,list,map(hash),zset(sorted set)等数据结构,用来替代或者与Redis配合存储十亿级别列表的数据。与Redis相比,SSDB的存储基于文件,因此可以存储更多的数据,而不受限于内存的大小。在实际应用中,我们使用SSDB存储网站实时流量数据。本文主要介绍如何搭建SSDB双主,并使用Keepalived做IP漂移,使得双主对客户端透明。只要双主中有一个服务正常,客户端就可以正常读写,并保证数据不会丢失。其结构如图所示:
安装SSDB
在两台服务器上下载SSDB源码包master.zip(下载地址),解压后先后执行“make”和“make install”完成安装:1
2
3
4unzip master.zip
cd ssdb-master
make
make install
SSDB默认安装至/usr/local/ssdb。
配置SSDB
修改/usr/local/ssdb中的配置文件ssdb.conf:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56# ssdb-server config
# MUST indent by TAB!
# 配置目录
work_dir = /data/ssdb-shard
pidfile = /data/ssdb-shard/ssdb.pid
# 配置访问
server:
# IP配置为0.0.0.0,则任何一个IP都可以访问
ip: 0.0.0.0
port: 8888
# 可以配置访问IP和访问密码,我们使用iptables配置访问IP,因此不在此处配置
# format: allow|deny: all|ip_prefix
# multiple allows or denys is supported
#deny: all
#allow: 127.0.0.1
#allow: 192.168
# auth password must be at least 32 characters
#auth: very-strong-password
# 配置同步和复制
# 双主下,当前SSDB是另一个SSDB的从,需要从另一个SSDB同步和复制数据
replication:
binlog: yes
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
# to identify a master even if it moved(ip, port changed)
# if set to empty or not defined, ip:port will be used.
id: svc_2
# sync|mirror, default is sync
# 由于双主是双向同步,如果使用sync,则会造成双主重复一直同步,死循环
type: mirror
ip: xx.xx.xx.xx
port: 8888
# 配置日志
logger:
level: error
output: log.txt
rotate:
size: 1000000000
# 配置LevelDB,SSDB使用LevelDB作为底层存储引擎
leveldb:
# in MB
cache_size: 500
# in KB
block_size: 32
# in MB
write_buffer_size: 64
# in MB
compaction_speed: 1000
# yes|no
compression: yes
启动SSDB
启动两台服务器上的SSDB:1
2 启动为后台进程(不阻塞命令行)
/usr/local/ssdb/ssdb-server -d ssdb.conf
使用/usr/local/ssdb/ssdb-cli进入命令行,使用info命令查看SSDB信息:
从replication信息可以看到当前SSDB作为另一个SSDB的从,而在另一个SSDB中通过info命令也可以看到其是当前SSDB的从。而在某个SSDB使用set命令写入一个键值时,在另一个SSDB使用get命令可读出这个键值,说明SSDB双主搭建成功,这两个SSDB只要有一个服务正常,就可以正常对外提供读写,并保证数据不会丢失。
配置Keepalived
对于客户端,在访问SSDB双主时,需要知道各个SSDB的地址,并且自己实现fail-over机制,在无法读写某个SSDB时,重新尝试读写另一个SSDB。我们使用Keepalived监控SSDB,对外提供虚IP供客户端连接读写,虚IP初始映射到某个SSDB,当该SSDB不可用时,将虚IP漂移到另一个SSDB,这样,双主对于客户端是透明的,客户端只要连接虚IP即可。此处不再介绍Keepalived的安装和运行,可参见《Keepalived介绍》,Keepalived的主配置keepalived.conf如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30! Configuration File for keepalived
global_defs {
router_id ssdb_1
}
vrrp_script chk_ssdb {
script "/usr/local/keepalived/scripts/ssdb_check.sh 127.0.0.1 8888"
interval 5
weight -2
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 225
priority 101
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
xx.xx.xx.xx
}
track_script {
chk_ssdb
}
}
其中每隔5秒执行一个脚本检查SSDB服务是否可用,如不可用,则将权重减小2至99,而Keepalived从配置中权重为100,因此,从切换为主,并配置虚IP,保证了虚IP所在的SSDB服务一直可用。ssdb_check.sh脚本如下所示:1
2
3
4
5
6
7
8
9
10
11
12
13
14 !/bin/bash
LOGFILE="/var/log/keepalived-ssdb-check.log"
if [ "`/usr/local/bin/redis-cli -h $1 -p $2 PING`" == "PONG" ]; then :
exit 0
else
sleep 1
if [ "`/usr/local/bin/redis-cli -h $1 -p $2 PING`" == "PONG" ]; then :
exit 0
else
date >> $LOGFILE
echo "Failed:redis-cli -h $1 -p $2 PING" >> $LOGFILE 2>&1
exit 1
fi
fi
由于SSDB兼容Redis部分协议,因此此处使用Redis的命令行工具PING SSDB检查服务是否可用。