1、编译
1.1、下载
wget --no-check-certificate https://github.com/ideawu/ssdb/archive/master.zip
1.2、编译
unzip master
cd ssdb-master
make
make install
2、主从部署
2.1、主节点配置
# ssdb-server config
# MUST indent by TAB!
work_dir = /data/ssdb/ssdb_8892
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8892.pid
server:
ip: 192.168.100.223
port: 8892
replication:
binlog: yes
capacity: 100000000
# 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_1
# sync|mirror, default is sync
#type: sync
#host: 10.1.100.224
#port: 8898
#auth: Zhuio#2025
#redis_host: localhost
#redis_port: 6379
#redis_auth: password
logger:
level: debug
output: /data/ssdb/ssdb_8892/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
2.2、从节点配置
# ssdb-server config
# MUST indent by TAB!
work_dir = /data/ssdb/ssdb_8893
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8893.pid
server:
ip: 192.168.100.224
port: 8893
#readonly: yes
replication:
binlog: yes
capacity: 100000000
# 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_1
# sync|mirror, default is sync
# type: sync
host: 192.168.100.223
port: 8892
# auth: password
# redis_host: localhost
# redis_port: 6379
# redis_auth: password
logger:
level: debug
output: /data/ssdb/ssdb_8893/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
2.3、启动服务
# 启动
/opt/apps/ssdb/ssdb-server -d /opt/apps/ssdb/cluster/conf/ssdb-8892.conf
/opt/apps/ssdb/ssdb-server -d /opt/apps/ssdb/cluster/conf/ssdb-8893.conf
# 停止
/opt/apps/ssdb/ssdb-server /opt/apps/ssdb/cluster/conf/ssdb-8892.conf -s stop
# 重启
/opt/apps/ssdb/ssdb-server -d /opt/apps/ssdb/cluster/conf/ssdb-8892.conf -s restart
# 检查服务状态
# 命令
ps faux | grep ssdb
netstat -ant | grep 8892
2.4、ssdb-cli登陆
# 登陆
/opt/apps/ssdb/ssdb-cli -h 192.168.100.223 -p 8892
# info命令可以返回SSDB服务状态
info
2.5、状态详解
- version:当前数据库的版本
- links:当前服务器的连接数
- total_calls:被调用总次数
- dbsize:数据库大小(字节数),数据库预估的大小(可能和硬盘占用差异非常大) . 如果服务器开启了压缩, 这个大小是压缩后的大小
- binlogs:当前实例的写操作状态
capacity: binlog 队列的最大长度
min_seq: 当前队列中的最小 binlog 序号
max_seq: 当前队列中的最大 binlog 序号
- replication:当此服务器有 master 或 slave 的时候才会有此信息,所以此信息并不一定出现(当为一台单点 ssdb
时就没有)
作为 master 时,信息格式如下
可以有多条 replication 记录. 每一条表示一个连接进来的 slave(client)
client host:port, 远端 slave 的 host:port
type: 类型, sync/mirror
status: 当前同步状态, DISCONNECTED/INIT/OUT_OF_SYNC/COPY/SYNC
last_seq: 上一条发送或者收到的 binlog 的序号
作为 slave 时,信息格式如下
一条表示一个当前服务器所连接的 master(slaveof).
slaveof host:port, 远端 master 的 host:port
type: 类型, sync/mirror
status: 当前同步状态, DISCONNECTED/INIT/OUT_OF_SYNC/COPY/SYNC
last_seq: 上一条发送或者收到的 binlog 的序号
slaveof.id: master 的 id (这是从 slave’s 角度来看的, 永远不需要在 master 上配置它自己的 id)
slaveof.copy_count: 在全量同步时, 已经复制的 key 的数量
slaveof.sync_count: 发送或者收到的 binlog 的数量
关于status:
DISCONNECTED: 与 master 断开了连接, 一般是网络中断
INIT: 初始化状态
OUT_OF_SYNC: 由于短时间内在 master 有大量写操作, 导致 binlog 队列淘汰, slave 丢失同步点, 只好重新复制全部的数据
COPY: 正在复制基准数据的过程中, 新的写操作可能无法及时地同步
SYNC: 同步状态是健康的
- serv_key_range:不同数据类型的 key 在 SSDB 中是排序的, 所以这个信息表示不同数据类型的最小 key 和最大 key
- leveldb.stats:这个信息显示了 LevelDB 每一层级的文件数量和文件总大小. 越小的层级如果文件越少, 那么数据库就越健康(查询更快速)
2.6、info cmd
cmd.* : 代表某子类命令的操作
calls: 该命令总共处理了多少次
time_wait: 命令在被处理前等待的总共时间(单位毫秒)
time_proc: 命令处理总共消耗的时间(单位毫秒)
3、双主部署
3.1、主节点realtime-dw1配置
# ssdb-server config
# MUST indent by TAB!
# ssdb-server config for slave
# relative to path of this file, directory must exists
work_dir = /data/ssdb/ssdb_8897
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8897.pid
server:
ip: 192.168.100.223
port: 8897
replication:
binlog: yes
capacity: 100000000
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
id: realtime-dw2
# sync|mirror, default is sync
type: mirror
host: 192.168.100.224
port: 8897
logger:
level: debug
output: /data/ssdb/ssdb_8897/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
3.2、主节点realtime-dw2配置
# ssdb-server config
# MUST indent by TAB!
# ssdb-server config for slave
# relative to path of this file, directory must exists
work_dir = /data/ssdb/ssdb_8897
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8897.pid
server:
ip: 10.1.100.224
port: 8897
replication:
binlog: yes
capacity: 100000000
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
id: realtime-dw1
# sync|mirror, default is sync
type: mirror
host: 10.1.100.223
port: 8897
logger:
level: debug
output: /data/ssdb/ssdb_8897/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
3.3、启动服务
# 启动
/opt/apps/ssdb/ssdb-server -d /opt/apps/ssdb/cluster/conf/ssdb-8897.conf
# 停止
/opt/apps/ssdb/ssdb-server /opt/apps/ssdb/cluster/conf/ssdb-8897.conf -s stop
3.4、服务验证
# 登陆realtime-dw1
/opt/apps/ssdb/ssdb-cli -h 192.168.100.223 -p 8897
set mic wanghaha
get mic
# 登陆realtime-dw2
/opt/apps/ssdb/ssdb-cli -h 192.168.100.224 -p 8897
get mic
4、多主部署
4.1、主节点realtime-dw1配置
# ssdb-server config
# MUST indent by TAB!
# ssdb-server config for slave
# relative to path of this file, directory must exists
work_dir = /data/ssdb/ssdb_8897
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8897.pid
server:
ip: 192.168.100.223
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
replication:
binlog: yes
capacity: 100000000
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
id: realtime-dw2
# sync|mirror, default is sync
type: mirror
host: 192.168.100.224
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
slaveof:
id: realtime-dw3
# sync|mirror, default is sync
type: mirror
host: 192.168.100.225
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
logger:
level: debug
output: /data/ssdb/ssdb_8897/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
4.2、主节点realtime-dw2配置
# ssdb-server config
# MUST indent by TAB!
# ssdb-server config for slave
# relative to path of this file, directory must exists
work_dir = /data/ssdb/ssdb_8897
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8897.pid
server:
ip: 192.168.100.224
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
replication:
binlog: yes
capacity: 100000000
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
id: realtime-dw1
# sync|mirror, default is sync
type: mirror
host: 192.168.100.223
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
slaveof:
id: realtime-dw3
# sync|mirror, default is sync
type: mirror
host: 192.168.100.225
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
logger:
level: debug
output: /data/ssdb/ssdb_8897/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
4.3、主节点realtime-dw3配置
# ssdb-server config
# MUST indent by TAB!
# ssdb-server config for slave
# relative to path of this file, directory must exists
work_dir = /data/ssdb/ssdb_8897
pidfile = /opt/apps/ssdb/cluster/pid/ssdb-8897.pid
server:
ip: 192.168.100.225
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
replication:
binlog: yes
capacity: 100000000
# Limit sync speed to *MB/s, -1: no limit
sync_speed: -1
slaveof:
id: realtime-dw1
# sync|mirror, default is sync
type: mirror
host: 192.168.100.223
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
slaveof:
id: realtime-dw2
# sync|mirror, default is sync
type: mirror
host: 192.168.100.224
port: 8897
auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
logger:
level: debug
output: /data/ssdb/ssdb_8897/ssdb.log
rotate:
size: 1000000000
leveldb:
# in MB
cache_size: 500
# in MB
write_buffer_size: 64
# in MB/s
compaction_speed: 1000
# yes|no
compression: yes
4.4、启动服务
# 启动
/opt/apps/ssdb/ssdb-server -d /opt/apps/ssdb/cluster/conf/ssdb-8897.conf
# 停止
/opt/apps/ssdb/ssdb-server /opt/apps/ssdb/cluster/conf/ssdb-8897.conf -s stop
# 重启
/opt/apps/ssdb/ssdb-server /opt/apps/ssdb/cluster/conf/ssdb-8897.conf -s restart
4.5、Twemproxy部署
- Twemproxy是一种代理分片机制,由Twitter开源。Twemproxy作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个Redis服务器,再原路返回。
- 该方案很好的解决了单个Redis实例承载能力的问题。当然,Twemproxy本身也是单点,需要用Keepalived做高可用方案。通过Twemproxy可以使用多台服务器来水平扩张redis服务,可以有效的避免单点故障问题。
- 使用Twemproxy代理来代理SSDB集群来实现数据的分布式存储,即shared。
4.6、编译安装autoconf
#安装编译环境
yum groupinstall "Development Tools"
#安装基本软件
yum install unzip vim wget lrzsz
cd /usr/local/src/
wget http://down1.chinaunix.net/distfiles/autoconf-2.69.tar.xz
xz -d autoconf-2.69.tar.xz
tar xf autoconf-2.69.tar
cd autoconf-2.69
./configure
make
make install
4.7、编译安装Twemproxy
# 依赖
yum install automake libtool autoconf -y
# 编译
cd /usr/local/src
wget https://codeload.github.com/twitter/twemproxy/zip/master
unzip master
cd twemproxy-master/
autoreconf -fvi
./configure --prefix=/usr/local/twemproxy
make -j 8
make install
4.8、配置Twemproxy
## 设置环境变量
vi /etc/profile
# twemproxy
PATH=$PATH:/usr/local/twemproxy/sbin/
#
source /etc/profile
## 创建相关目录(存放配置文件和pid文件)
cd /usr/local/twemproxy/
mkdir run conf
4.9、添加proxy配置文件
vim /usr/local/twemproxy/conf/nutcracker.yml
twemproxy:
## 监听地址和端口
listen: 192.168.100.211:22121
## 散列算法
hash: fnv1a_64
## 分片的算法,有ketama(一致性hash)、module(取模)、random(随机)三种算法
distribution: ketama
## 是否在节点无法响应时自动从服务器列表中剔除,重新响应时自动加入服务器列表中
auto_eject_hosts: true
## 后端代理的是否为redis
redis: true
redis_auth: 629568a1-18f9-4826-a3fe-a604fff16f5d
server_retry_timeout: 2000
server_failure_limit: 1
servers:
- 192.168.100.223:8897:1 realtime-dw1
- 192.168.100.224:8897:1 realtime-dw2
- 192.168.100.225:8897:1 realtime-dw3
listen
twemproxy监听的端口。可以以ip:port或name:port的形式来书写。
hash
可以选择的key值的hash算法:
> one_at_a_time
> md5
> crc16
> crc32(crc32 implementation compatible with libmemcached)
> crc32a(correct crc32 implementation as per the spec)
> fnv1_64
> fnv1a_64
> fnv1_32
> fnv1a_32
> hsieh
> murmur
> jenkins
如果没选择,默认是fnv1a_64。
hash_tag
hash_tag允许根据key的一个部分来计算key的hash值。hash_tag由两个字符组成,一个是hash_tag的开始,另外一个是hash_tag的结束,在hash_tag的开始和结束之间,是将用于计算key的hash值的部分,计算的结果会用于选择服务器。
例如:如果hash_tag被定义为”{}”,那么key值为"user:{user1}:ids"和"user:{user1}:tweets"的hash值都是基于”user1”,最终会被映射到相同的服务器。而"user:user1:ids"将会使用整个key来计算hash,可能会被映射到不同的服务器。
distribution
存在ketama、modula和random3种可选的配置。其含义如下:
(1)ketama
ketama一致性hash算法,会根据服务器构造出一个hash ring,并为ring上的节点分配hash范围。ketama的优势在于单个节点添加、删除之后,会最大程度上保持整个群集中缓存的key值可以被重用。
(2)modula
modula非常简单,就是根据key值的hash值取模,根据取模的结果选择对应的服务器。
(3)random
random是无论key值的hash是什么,都随机的选择一个服务器作为key值操作的目标。
timeout
单位是毫秒,是连接到server的超时值。默认是永久等待。
backlog
监听TCP 的backlog(连接等待队列)的长度,默认是512。
preconnect
是一个boolean值,指示twemproxy是否应该预连接pool中的server。默认是false。
redis
是一个boolean值,用来识别到服务器的通讯协议是redis还是memcached。默认是false。
server_connections
每个server可以被打开的连接数。默认,每个服务器开一个连接。
auto_eject_hosts
是一个boolean值,用于控制twemproxy是否应该根据server的连接状态重建群集。这个连接状态是由server_failure_limit 阀值来控制。
默认是false。
server_retry_timeout
单位是毫秒,控制服务器连接的时间间隔,在auto_eject_host被设置为true的时候产生作用。默认是30000 毫秒。
server_failure_limit
控制连接服务器的次数,在auto_eject_host被设置为true的时候产生作用。默认是2。
servers
左半部分是一个pool中的服务器的地址、端口和权重的列表,中间一个空格,后半部分是一个可选的服务器的名字,如果提供服务器的名字,将会使用它决定server的次序,从而提供对应的一致性hash的hash ring。否则,将使用server被定义的次序
4.10、启动Twemproxy测试服务
#创建软链
cd /usr/bin && ln -s /usr/local/twemproxy/sbin/nutcracker ./
#测试配置文件是否有语法错误
nutcracker -t -c /usr/local/twemproxy/conf/nutcracker.yml
#启动Twemproxy
nutcracker -d -c /usr/local/twemproxy/conf/nutcracker.yml -p /usr/local/twemproxy/run/nutcracker.pid -o /usr/local/twemproxy/run/nutcracker.log
#检查启动情况
ps -ef |grep nutcracker
netstat -lntup |grep 22121
tailf /usr/local/twemproxy/run/nutcracker.log
4.11、查看进程及测试
# 查看进程
ps -ef | grep nutcracker | grep -v grep
# 安装redis-cli
yum -y install redis
# 登陆
redis-cli -h 192.168.100.211 -p 22121 -a 629568a1-18f9-4826-a3fe-a604fff16f5d
# 操作
set name zhangsan
# 验证
/opt/apps/ssdb/ssdb-cli -h 192.168.100.225 -p 8897
get name
4.12、配置启动/重启/停止脚本操作
启动脚本 start.sh
#!/bin/sh
nutcracker -d -c /usr/local/twemproxy/conf/nutcracker.yml -p /usr/local/twemproxy/run/nutcracker.pid -o /usr/local/twemproxy/run/nutcracker.log
停止脚本stop.sh
#!/bin/sh
sudo killall nutcracker
5、构建高可用集群架构
5.1、使用 Twemproxy 和 Sentinel 构建高可用集群架构
使用 Sentinel 构建的主从复制架构,能够实现高可用,但是不能解决单个 Redis 节点的数据量过大的问题,如果单个 Redis 节点的数据量过大,主机内存过载,那么就需要使用 Redis 的集群架构来将数据进行分片处理,使其分布在不同的物理机上面,使其能够做到容量的扩展 。
Twemproxy + Sentinel 组合架构的优点
- 通过 Sentinel 能够做到 Redis 节点的失效救援。
- 配置简单且 Twemproxy 具有高并发的能力。
- 能够均衡 Redis的负载,提高 Redis 的吞吐能力。
- 通过 Twemproxy 配置多个 Redis 节点,能够显著提高单节点容量的限制。
Twemproxy + Sentinel 组合架构的缺点
- Twemproxy 实际上会给 Redis 带来一定的性能损耗。
- Twemproxy 无法很好解决 Redis 扩容的问题,添加或者减少 Redis 节点时,不能够自动进行节点数据的再分配。
- 需要使用 Keepalived 来解决 Twemproxy 单点的问题,给系统增加了复杂度。