Redis 是一个高性能的key-value数据库。它支持存储多种value类型,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。同时,为了保证效率,数据都是缓存在内存中。Redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。
准备工作
要让集群正常工作至少需要3个主节点,在这里我们要创建6个redis节点并部署到2台物理节点上,其中三个为主节点,三个为从节点,对应的redis节点的ip和端口对应关系如下)
192.168.1.121:7000
192.168.1.121:7001
192.168.1.121:7002
192.168.1.122:7000
192.168.1.122:7001
192.168.1.122:7002
一、安装Redis
- 下载redis,这里需要下载3.0之后的版本,之前的版本不支持集群模式,本文采用最新的3.0.7版本。(所有节点)
cd /home/soft
wget http://download.redis.io/releases/redis-3.0.7.tar.gz
- 解压,编译
编译前确保安装好了gcc
(所有节点)
tar -zxvf redis-3.0.7.tar.gz
cd /home/soft/redis3.0.7
make
make install
- 创建集群需要的目录(节点1)
mkdir -p /home/soft/cluster
cd /home/soft/cluster
mkdir 7000
mkdir 7001
mkdir 7002
- 修改配置文件redis.conf(节点1)
cp /home/soft/redis3.0.7/redis.conf /home/soft/cluster
vi redis.conf
修改配置文件中的下面选项
port 7000
daemonize yes
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
- 修改完redis.conf配置文件中的这些配置项之后把这个配置文件分别拷贝到7000/7001/7002目录下面(节点1)
cp /home/soft/cluster/redis.conf /home/soft/cluster/7000
cp /home/soft/cluster/redis.conf /home/soft/cluster/7001
cp /home/soft/cluster/redis.conf /home/soft/cluster/7002
注意:拷贝完成之后要修改7001/7002目录下面redis.conf文件中的port参数,分别改为对应的文件夹的名称。
- 将节点1上的cluster目录拷贝到其他节点上(节点1)
scp -r /home/soft/cluster root@192.168.1.122:/home/soft/
- 分别启动这6个redis实例
//节点1
cd /home/soft/cluster/7000
redis-server redis.conf
cd /home/soft/cluster/7001
redis-server redis.conf
cd /home/soft/cluster/7002
redis-server redis.conf
//节点2
cd /home/soft/cluster/7000
redis-server redis.conf
cd /home/soft/cluster/7001
redis-server redis.conf
cd /home/soft/cluster/7002
redis-server redis.conf
- 启动之后使用命令查看redis的启动情况
ps -ef|grep redis
如下图显示则说明对应节点的redis实例启动成功。
二、创建集群
- 安装ruby环境
yum -y install ruby
- 安装rubygems
yum -y install rubygems
- 安装gem redis
gem install -l redis
- 执行redis的创建集群命令创建集群(单节点即可)
cd /home/soft/redis3.0.7/src
./redis-trib.rb create --replicas 1 192.168.1.121:7000 192.168.1.121:7001 192.168.1.121:7002 192.168.1.122:7000 192.168.1.122:7001 192.168.1.122:7002
--replicas表示为每个master节点创建多少个slave节点。
创建过程中,redis-trib 会打印出一份预想中的配置给你看, 如果你觉得没问题的话, 就可以输入 yes , redis-trib 就会将这份配置应用到集群当中,让各个节点开始互相通讯,配置完成。
至此redis集群即搭建成功!
- 使用redis-cli命令进入集群环境
redis-cli -c -p 7000
//或者指定访问ip
redis-cli -c -p 7000 -h 192.168.1.121
简单测试下
从图中可以看出,它总是依靠 Redis 集群节点来将它转向(redirect)至正确的节点。
三、设置开机自启
- 设置redis.conf中daemonize为yes,确保守护进程开启。
- 编写开机自启动脚本
vi /etc/init.d/redis7000
脚本内容如下:
# chkconfig: 2345 10 90
# description: Start and Stop redis
PATH=/usr/local/bin:/sbin:/usr/bin:/bin
REDISPORT=7000
EXEC=/usr/local/bin/redis-server
REDIS_CLI=/usr/local/bin/redis-cli
PIDFILE=/var/run/redis.pid
CONF="/home/soft/cluster/7000/redis.conf"
AUTH=""
case "$1" in
start)
if [ -f $PIDFILE ]
then
echo "$PIDFILE exists, process is already running or crashed."
else
echo "Starting Redis server..."
$EXEC $CONF
fi
if [ "$?"="0" ]
then
echo "Redis is running..."
fi
;;
stop)
if [ ! -f $PIDFILE ]
then
echo "$PIDFILE exists, process is not running."
else
PID=$(cat $PIDFILE)
echo "Stopping..."
$REDIS_CLI -p $REDISPORT SHUTDOWN
sleep 2
while [ -x $PIDFILE ]
do
echo "Waiting for Redis to shutdown..."
sleep 1
done
echo "Redis stopped"
fi
;;
restart|force-reload)
${0} stop
${0} start
;;
*)
echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2
exit 1
esac
编写完成后保存退出。
- 设置权限
chmod 755 redis
- 启动
/etc/init.d/redis7000 start
启动成功会提示如下信息:
Starting Redis server...
Redis is running...
- 设置开机自启动
chkconfig redis on
- 关机重启测试
reboot
四、Cluster操作
- 集群
CLUSTER INFO 打印集群的信息
CLUSTER NODES 列出集群当前已知的所有节点(node),以及这些节点的相关信息。
- 节点
CLUSTER MEET <ip> <port> 将 ip 和 port 所指定的节点添加到集群当中,让它成为集群的一份子。
CLUSTER FORGET <node_id> 从集群中移除 node_id 指定的节点。
CLUSTER REPLICATE <node_id> 将当前节点设置为 node_id 指定的节点的从节点。
CLUSTER SAVECONFIG 将节点的配置文件保存到硬盘里面。
- 槽(slot)
CLUSTER ADDSLOTS <slot> [slot ...] 将一个或多个槽(slot)指派(assign)给当前节点。
CLUSTER DELSLOTS <slot> [slot ...] 移除一个或多个槽对当前节点的指派。
CLUSTER FLUSHSLOTS 移除指派给当前节点的所有槽,让当前节点变成一个没有指派任何槽的节点。
CLUSTER SETSLOT <slot> NODE <node_id> 将槽 slot 指派给 node_id 指定的节点,如果槽已经指派给另一个节点,那么先让另一个节点删除该槽>,然后再进行指派。
CLUSTER SETSLOT <slot> MIGRATING <node_id> 将本节点的槽 slot 迁移到 node_id 指定的节点中。
CLUSTER SETSLOT <slot> IMPORTING <node_id> 从 node_id 指定的节点中导入槽 slot 到本节点。
CLUSTER SETSLOT <slot> STABLE 取消对槽 slot 的导入(import)或者迁移(migrate)。
- 键
CLUSTER KEYSLOT <key> 计算键 key 应该被放置在哪个槽上。
CLUSTER COUNTKEYSINSLOT <slot> 返回槽 slot 目前包含的键值对数量。
CLUSTER GETKEYSINSLOT <slot> <count> 返回 count 个 slot 槽中的键。
五、客户端操作
需要注意的是集群模式目前不支持多数据库操作,即只能使用database 0,使用select命令会报错
。
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(20);
config.setMaxIdle(2);
Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
jedisClusterNodes.add(new HostAndPort("192.168.1.121", 7000));
jedisClusterNodes.add(new HostAndPort("192.168.1.121", 7001));
jedisClusterNodes.add(new HostAndPort("192.168.1.121", 7002));
jedisClusterNodes.add(new HostAndPort("192.168.1.122", 7000));
jedisClusterNodes.add(new HostAndPort("192.168.1.122", 7001));
jedisClusterNodes.add(new HostAndPort("192.168.1.122", 7002));
// 超时,最大的转发数,最大链接数,最小链接数都会影响到集群
JedisCluster jedisCluster = new JedisCluster(jedisClusterNodes, 5000, 10, config);
jedisCluster.set("key","value");