9.实践NoSQL-Redis多实例及集群服务(下)
9.实践NoSQL-Redis多实例及集群服务(下)
Redis也是一个应用广泛的Key-Value类型的No SQL数据库,Redis最突出的特点就是支持内存缓存及持久化存储,且所支持的数据库类型更丰富,还支持队列,并可以实现主从集群和分布式,尽管Redis在DBEngine-Rank 9月份的排名(第8)没有MogonDB(第5)那么靠前,但也是目前主流的No SQL数据库之一。
和大家熟悉的Memcached相比,Redis所支持的存储值的类型更多,如包括string(字符串),list(链表),set(集合)和zset(有序集合)等,且具有更加丰富的原子性操作,此外和Memcached还有一大区别就是,Redis周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,实现持久化存储。
Redis的出现、很大程度弥补了Memcached的不足,实际应用中,Redis完全可以取代Memcached。此外,Redis还提供了JavaScript,Python,Ruby及PHP等流行开发语言的客户端,易于使用且保持高效,Redis官方网站的地址如下:
http://www.redis.io/
多数情况下,Redis是以单节点单实例的方式安装和配置,这样使用没有什么不妥,就是浪费资源,在服务器资源充足的情况下,可以多实例的方式来使用Redis,以便充分利用服务器资源,物尽其用。
9.1. Redis单节点多实例的规划,部署和配置
9.1.1. 多实例规划
Redis主目录:/data/redis
Redis端口:6381,6382,6383
Redis主配置文件规划如下:
/data/redis/conf/redis-6381.conf
/data/redis/conf/redis-6382.conf
/data/redis/conf/redis-6383.conf
Redis日志文件规划如下:
/data/redis/log/redis-6381.log
/data/redis/log/redis-6382.log
/data/redis/log/redis-6383.log
Redis PID文件目录规划如下:
/data/redis/pidfile/redis_6381.pid
/data/redis/pidfile/redis_6382.pid
/data/redis/pidfile/redis_6383.pid
Redis数据目录规划如下:
/data/redis/data/6381
/data/redis/data/6382
/data/redis/data/6383
9.1.2.部署Redis
源代码编译安装
运行如下命令下载指定版本源码包,源码包的版本可以从https://redis.io/download选择下载,关键操作如下:
◆准备工作
运行如下命令安装Redis所需软件包:
dnf install -y '@Development tools' tcl
◆编译安装
具体操作如下:
cd /usr/local/src
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar xzf redis-5.0.5.tar.gz
cd redis-5.0.5/ #切换至解压后的目录
make
make install PREFIX=/data/redis-5.0.5
ln -s /data/redis-5.0.5 /data/redis
mkdir /data/redis/conf
mkdir /data/redis/log
mkdir /data/redis/data
mkdir /data/redis/pidfile
mkdir /data/redis/data/{6381,6382,6383}
9.1.3.配置Redis
◆复制配置文件
使用如下命令复制Redis的主配置文件:
cp ./redis.conf /data/redis/conf/redis-6381.conf #当前目录为redis-5.0.5,默认配置文件位置redis-5.0.5/redis.conf
cp ./redis.conf /data/redis/conf/redis-6382.conf
cp ./redis.conf /data/redis/conf/redis-6383.conf
复制源代码中的redis.conf默认配置文件到指定目录,修改默认端口,并且以守护进程方式运行Redis,最后使用编辑器修改各个实例的配置文件,具体操作如下:
cd /data/redis/conf
vi redis-6381.conf
配置文件内容如下:
port 6381 #指定Redis的端口号,默认端口为6379
logfile "/data/redis/log/redis-6381.log" #定义Redis日志文件路径,默认为空
bind 192.168.1.168 127.0.0.1 #所绑定的IP地址
daemonize yes #定义以守护进程方式启动Redis,默认值为no
pidfile "/data/redis/pidfile/redis_6381.pid" #指定pid 文件,默认为redis_6379.pid
dbfilename redis-6381.rdb #定义RDB持久化文件名,默认为dump.rdb
appendfilename "redis-6381.aof" #指定AFO持久化文件名,默认为appendonly.aof
dir "/data/redis/data/6381" #指定Redis持久化文件路径
确认无误,保存退出后即可以此为蓝本,复制和修改出其他端口的配置文件。
9.1.4.管理Redis多实例
成功创建各端口配置文件,即可启动Redis的各个实例:
redis-server /data/redis/conf/redis-6381.conf
redis-server /data/redis/conf/redis-6382.conf
redis-server /data/redis/conf/redis-6383.conf
Tips:将Redis的路径加入到系统
将Redis的路径加入到系统,就不用输入长长的路径名称了,具体实现如下:
echo "PATH=$PATH:/data/redis/bin/" >> /etc/profile
source /etc/profile
亦可沿袭MongoDB中的写法,/etc/profile.d目录下创建一个redis.sh脚本。脚本运行后便可运行如下命令检测Redis是否启动成功:
ss -tnlp | grep 6381
ss -tnlp | grep 6382
ss -tnlp | grep 6383
还可用如下命令检测:
lsof -i:6381
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 14069 root 6u IPv4 49006 0t0 TCP localhost:6381 (LISTEN)
[root@localhost bin]# lsof -i:6382
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 14075 root 6u IPv4 49016 0t0 TCP localhost:metatude-mds (LISTEN)
[root@localhost bin]# lsof -i:6383
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 14080 root 6u IPv4 49023 0t0 TCP localhost:6383 (LISTEN)
如需关闭Redis多实例,可用如下命令:
ps -wux | grep 'redis-server' | grep -v 'grep' | awk '{print $2}' | xargs kill -9
Tips:创建启动脚本和关闭脚本
◆启动脚本
执行如下命令创建Redis启动脚本:
vi start_multiport.sh
redis-server /data/redis/conf/redis-6381.conf
redis-server /data/redis/conf/redis-6382.conf
redis-server /data/redis/conf/redis-6383.conf
◆关闭脚本
执行如下命令创建Redis关闭脚本:
vi stop_multiport.sh
ps -wux | grep 'redis-server' | grep -v 'grep' | awk '{print $2}' | xargs kill -9
最后添加执行权限:
chmod +x start_multiport.sh
chmod +x stop_multiport.sh
9.1.5.Redis客户端的使用
在检测Redis安装时,已经用到了redis-cli命令,下面来Redis客户端连接所创建的实例:
redis-cli -h 192.168.1.168 -p 6381 -c
redis-cli -h 192.168.1.168 -p 6382 -c
redis-cli -h 192.168.1.168 -p 6383 -c
◆获得的帮助
运行redis-cli命令进入Redis命令行后,可用如下命令获取帮助:
127.0.0.1:6381> help get
GET key
summary: Get the value of a key
since: 1.0.0
group: string
◆查看所有的key列表
127.0.0.1:6381> keys *
1) "test"
◆增加两条记录key1和key2
key1为字符串,key2为数值,具体方法如下:
127.0.0.1:6381> set key1 "PUU"
OK
127.0.0.1:6381> set key2 1
OK
◆打印记录
127.0.0.1:6381> get key1
"PUU"
◆数字自增
127.0.0.1:6381> INCR key2
(integer) 2
127.0.0.1:6381> INCR key2
(integer) 3
两次自增后打印记录:
127.0.0.1:6381> get key2
"3"
9.2. 创建Redis三节点集群
Redis集群中至少应该有三个节点,此外,还要保证集群的高可用,需要每个节点有一个备份节点,故Redis集群至少需要6台服务器。还有一种搭建伪分布式,可以使用一个节点运行6个redis实例,这样就需要修改redis的端口号7001-7006。
服务器Redis集群IP分配:
R1:192.168.1.164
R2:192.168.1.165
R3:192.168.1.166
每个物理节点都有一个主节点和备份节点。
9.2.1.部署和配置
◆准备工作
执行如下命令完成Redis部署的准备工作:
dnf install '@Development tools' tcl wget -y
◆部署
随后便可下载源代码,配置,编译和安装了,关键操作如下:
cd /usr/local/src
wget http://download.redis.io/releases/redis-5.0.5.tar.gz
tar xzf redis-5.0.5.tar.gz
cd redis-5.0.5/
make
make install PREFIX=/data/redis-5.0.5
◆配置
执行如下操作进行安装后的配置:
ln -s /data/redis-5.0.5 /data/redis
mkdir /data/redis/conf
mkdir /data/redis/log
mkdir /data/redis/data
mkdir /data/redis/pidfile
随后还需将Redis的路径导入环境变量:
echo "PATH=$PATH:/data/redis/bin/" >> /etc/profile
source /etc/profile
◆测试
执行如下命令测试Redis的安装:
redis-server #启动Redis服务器
redis-cli
redis> set hello world
OK
redis> get hello
"world"
9.2.2.Redis集群节点目录规划和创建
◆Redis集群目录规划 /data/redis |
-- bin | -- redis-benchmark | -- redis-check-aof | -- redis-check-rdb | -- mkreleasehdr.sh | -- redis-cli | -- redis-sentinel -> redis-server | `-- redis-server | -- conf | -- redis-7001.conf | -- redis-7002.conf | -- redis-7003.conf | -- redis-7004.conf | -- redis-7005.conf | -- redis-7006.conf |
---|
`-- log | -- redis-7001.log | -- redis-7002.log | -- redis-7003.log | -- redis-7004.log | -- redis-7005.log | -- redis-7006.log |
---|
`-- pidfile
| |-- redis-7001.pid
| |-- redis-7002.pid
| |-- redis-7003.pid
| |-- redis-7004.pid
| |-- redis-7005.pid
| |-- redis-7006.pid
◆Redis集群创建和配置
R1节点预配置操作如下:
hostnamectl set-hostname R1
vi /etc/hosts
添加如下内容:
192.168.1.164 R1
192.168.1.165 R2
192.168.1.166 R3
R1节点集群配置操作如下:
vi /data/redis/conf/redis-7001.conf
配置内容如下:
appendonly yes
bind 0.0.0.0
cluster-enabled yes
cluster-config-file "nodes-7001.conf"
cluster-node-timeout 5000
daemonize yes
port 7001
pidfile "/data/redis/pidfile/redis_7001.pid"
logfile "/data/redis/log/redis-7001.log"
7002端口配置如下:
vi /data/redis/conf/redis-7002.conf
配置内容如下:
appendonly yes
bind 0.0.0.0
cluster-enabled yes
cluster-config-file "nodes-7002.conf"
cluster-node-timeout 5000
daemonize yes
port 7002
pidfile "/data/redis/pidfile/redis_7002.pid"
logfile "/data/redis/log/redis-7002.log"
R2和R3节点重复同样的操作,此处不做赘述,切记修改端口号及相关配置,Redis高频配置选项如下:
◆port 7001 #Redis所监听端口
◆bind 0.0.0.0 #允许所有IP连接,如不配置和配置0.0.0.0一样
◆cluster-enabled yes #是否可以作为集群的一个node
◆daemonize no #启动后是否作为服务在后台运行
◆requirepass 12345678 #用户该节点时使用的密码
◆masterauth 12345678 #作为从节点时使用该密码连接主节点
◆protected-mode no #是否运行在保护模式,保护模式不允许从主机外的地方连接
9.2.3.启动集群的各个节点
◆创建Redis集群启动脚本
vi start_cluster.sh
脚本内容如下:
#!/bin/bash
nohup redis-server /data/redis/conf/redis-7001.conf > log.log 2>&1 &
nohup redis-server /data/redis/conf/redis-7002.conf > log.log 2>&1 &
◆启动各个节点
成功创建脚本后,执行如下命令启动Redis集群:
chmod +x ./start_cluster.sh
./start_cluster.sh
◆检测各个节点
执行如下命令检测各个节点:
lsof -i:7001
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 30921 root 6u IPv4 65377 0t0 TCP *:afs3-callback (LISTEN)
[root@R1 ~]# lsof -i:7002
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
redis-ser 30930 root 6u IPv4 65383 0t0 TCP *:afs3-prserver (LISTEN)
上述完成的仅是一台服务器的,其他服务器如法炮制即可。
9.2.4.创建和管理Redis集群
运行如下命令创建集群:
/data/redis/bin/redis-cli --cluster create 192.168.1.164:7001 192.168.1.164:7002 192.168.1.165:7003 192.168.1.165:7004 192.168.1.166:7005 192.168.1.166:7006 --cluster-replicas 1
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.1.165:7004 to 192.168.1.164:7001
Adding replica 192.168.1.166:7006 to 192.168.1.165:7003
Adding replica 192.168.1.164:7002 to 192.168.1.166:7005
M: 70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1 192.168.1.164:7001
slots:[0-5460] (5461 slots) master
S: a2ab6d71af7a015dd83820988054bbd342b08b57 192.168.1.164:7002
replicates 25d5fd8de623f69b33e00c721445261b02bffca1
M: 9a65be175aef5c60bc5f4d1bbde55fcc0594d030 192.168.1.165:7003
slots:[5461-10922] (5462 slots) master
S: 264dfcc81331565b4ce9b9a557199cdea41f0e7d 192.168.1.165:7004
replicates 70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1
M: 25d5fd8de623f69b33e00c721445261b02bffca1 192.168.1.166:7005
slots:[10923-16383] (5461 slots) master
S: 4e854d54def80755dd2ade26f9bebe6207a824cc 192.168.1.166:7006
replicates 9a65be175aef5c60bc5f4d1bbde55fcc0594d030
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 192.168.1.164:7001)
M: 70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1 192.168.1.164:7001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: 264dfcc81331565b4ce9b9a557199cdea41f0e7d 192.168.1.165:7004
slots: (0 slots) slave
replicates 70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1
M: 9a65be175aef5c60bc5f4d1bbde55fcc0594d030 192.168.1.165:7003
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 4e854d54def80755dd2ade26f9bebe6207a824cc 192.168.1.166:7006
slots: (0 slots) slave
replicates 9a65be175aef5c60bc5f4d1bbde55fcc0594d030
S: a2ab6d71af7a015dd83820988054bbd342b08b57 192.168.1.164:7002
slots: (0 slots) slave
replicates 25d5fd8de623f69b33e00c721445261b02bffca1
M: 25d5fd8de623f69b33e00c721445261b02bffca1 192.168.1.166:7005
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
三个节点的Redis集群,需要三个IP地址,每个IP地址绑定2个端口即可。最后运行如下命令查看集群各个节点的信息:
redis-cli -p 7001
> cluster info #获得Redis集群运行情况
cluster_state:ok #OK说明集群工作正常
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:769
cluster_stats_messages_pong_sent:764
cluster_stats_messages_sent:1533
cluster_stats_messages_ping_received:759
cluster_stats_messages_pong_received:769
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:1533
> cluster nodes #获得Redis集群节点信息
264dfcc81331565b4ce9b9a557199cdea41f0e7d 192.168.1.165:7004@17004 slave 70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1 0 1563567887000 4 connected
70ca99b8dde0accc5dbe3a9fa824f24bb18eabf1 192.168.1.164:7001@17001 myself,master - 0 1563567887000 1 connected 0-5460
9a65be175aef5c60bc5f4d1bbde55fcc0594d030 192.168.1.165:7003@17003 master - 0 1563567887881 3 connected 5461-10922
4e854d54def80755dd2ade26f9bebe6207a824cc 192.168.1.166:7006@17006 slave 9a65be175aef5c60bc5f4d1bbde55fcc0594d030 0 1563567888888 6 connected
a2ab6d71af7a015dd83820988054bbd342b08b57 192.168.1.164:7002@17002 slave 25d5fd8de623f69b33e00c721445261b02bffca1 0 1563567888384 5 connected
25d5fd8de623f69b33e00c721445261b02bffca1 192.168.1.166:7005@17005 master - 0 1563567888000 5 connected 10923-16383
> info replication #获得replication运行状态
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.1.165,port=7004,state=online,offset=322,lag=1
master_replid:d02472d30371a6dfb54cfa8ebd65a27c5ccfa548
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:322
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:322
Redis更多命令请参照如下网站:
http://redisdoc.com/
◆Redis集群关闭脚本
各节点创建并运行Redis集群关闭脚本:
vi stop_cluster.sh
脚本内容如下:
#!/bin/bash
ps -wux | grep 'redis-server' | grep -v 'grep' | awk '{print $2}' | xargs kill -9
并添加执行权限:
chmod +x stop_cluster.sh
然后,登录到R1执行如下命令实现Redis集群各个节点的安全认证操作:
/data/redis/bin/redis-cli -h 192.168.1.164 -p 7001 -c
> cluster info
> config set masterauth 12345678
OK
> config set requirepass 12345678
OK
这几步操作完成后,就完成了添加密码的操作。密码是12345678。需要注意的是,建议使用redis-trib.rb工具构建集群,集群构建完成前不要配置密码,集群构建完毕再通过config set + config rewrite命令逐个节点设置密码,此外,对集群设置密码,那么requirepass和masterauth都需要设置,否则发生主从切换时,就会遇到授权问题,可以模拟并观察日志。
最后,各个节点的密码都必须一致,否则Redirected就会失败,成功启用安全认证后,可用如下命令登录:
redis-cli -h 192.168.1.164 -p 7001 -c -a '12345678'
> config rewrite #将上述配置写到配置文件,且不用重启Redis集群
OK
启用安全认证并写入到文件后,各节点的redis.conf就多了几行内容:
masterauth "12345678"
requirepass "12345678"
如Replica节点的上述2条认证配置丢失了,将导致redis-trib.rb check时候发现无法连接到部分主机。如果出现这种情况的话,手动编辑redis.conf将上面的认证参数加进去,重启redis即可。
本章小结
本章帮助大家掌握了时下流行的NoSQL-Redis的单节点多实例和多节点集群的部署及配置方法,几乎是纯实战,配置难度中等,但步骤十分繁琐,不小心的话,很容易出错,对于初次接触的朋友来说也算是一个不小的挑战了。
EOF
扩展阅读
Benchmark: Shared vs. Dedicated Redis Instances
https://redislabs.com/blog/benchmark-shared-vs-dedicated-redis-instances/
First Step to Redis Cluster
https://blog.usejournal.com/first-step-to-redis-cluster-7712e1c31847
Intro to Redis Cluster Sharding – Advantages, Limitations, Deploying & Client Connections
https://dev.to/scalegrid/intro-to-redis-cluster-sharding--advantages-limitations-deploying--client-connections-5g82
Partitioning: how to split data among multiple Redis instances.
https://redis.io/topics/partitioning
参考文档br/>https://zh.wikipedia.org/wiki/Redis
https://en.wikipedia.org/wiki/Redis
http://redisdoc.com/
https://redis.io/documentation
https://redis.io/commands
https://medium.com/@MauroMorales/running-multiple-redis-on-a-server-472518f3b603
https://redis.io/topics/cluster-spec
https://medium.com/@iamvishalkhare/create-a-redis-cluster-faa89c5a6bb4