Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。
Redis 是一个高性能的key-value数据库。 redis的出现,很大程度补偿了memcached这类key/value存储的不足,在部 分场合可以对关系数据库起到很好的补充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客户端。
Redis支持主从同步。数据可以从主服务器向任意数量的从服务器上同步,从服务器可以是关联其他从服务器的主服务器。这使得Redis可执行单层树复制。存盘可以有意无意的对数据进行写操作。由于完全实现了发布/订阅机制,使得从数据库在任何地方同步树时,可订阅一个频道并接收主服务器完整的消息发布记录。同步对读取操作的可扩展性和数据冗余很有帮助。
redis支持的数据类型
字符串(strings)
散列(hashes)
列表(lists)
集合(sets)
有序集合(sorted sets)
###1.软件安装部署###
编译安装
[root@server1 ~]# tar zxf redis-6.2.4.tar.gz
[root@server1 ~]# cd redis-6.2.4/
[root@server1 redis-6.2.4]# make
[root@server1 redis-6.2.4]# make install
[root@server1 redis-6.2.4]# cd utils/
[root@server1 utils]# vim install_server.sh
注释以下行
...
#_pid_1_exe="$(readlink -f /proc/1/exe)"
#if [ "${_pid_1_exe##*/}" = systemd ]
#then
# echo "This systems seems to use systemd."
# echo "Please take a look at the provided example service unit files in this directory, and adapt and install them. Sorry!"
# exit 1
#fi
#unset _pid_1_exe
运行安装脚本
[root@server1 utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@server1 utils]# netstat -antlp|grep :6379
tcp 0 0 127.0.0.1:6379 0.0.0.0:* LISTEN 17478/redis-server
tcp6 0 0 ::1:6379 :::* LISTEN 17478/redis-server
[root@server1 utils]# vim /etc/redis/6379.conf
#监听本机所有接口
bind *
重启服务
[root@server1 utils]# /etc/init.d/redis_6379 restart
[root@server1 utils]# netstat -antlp|grep :6379
tcp 0 0 0.0.0.0:6379 0.0.0.0:* LISTEN 17533/redis-server
运行自带的安装程序,安装失败,修改文件,重新安装。
此时切换到配置目录下,可以看到自动生成了配置文件,查看端口,端口开启。修改该配置文件,重启服务。
###2.redis常用指令###
config get * //查看配置
select 1 //选择数据库
flushdb //清空当前数据库
flushall //清空所有数据库
move key 1 //移动key
del key //删除
rename oldkey newkey //改名
expire key 10 //设置过期时间
persist key //设置持久化
keys user* //查询
exists key //判断是否存在
###3.redis主从复制###
slaveof 172.25.0.11 6379min-slaves-to-write <slave 数量 >min-slaves-max-lag < 秒数 >Redis 使用异步复制,因此无法确保 slave 是否实际接收到给定的写命令
(1)master节点操作
创建redis实例,直接从server1上拷贝编译好的redis程序,两边都要安装rsync命令
[root@server1 ~]# cd /usr/local/bin/
[root@server1 bin]# yum install -y rsync
[root@server3 ~]# yum install -y rsync
拷贝程序
[root@server1 bin]# rsync -a redis-* server3:/usr/local/bin/
[root@server1 ~]# rsync -a redis-6.2.4 server3:
(2)slave节点配置
server3上完成redis部署
[root@server3 ~]# cd /usr/local/bin/
[root@server3 bin]# ls
redis-benchmark redis-check-aof redis-check-rdb redis-cli redis-sentinel redis-server
[root@server3 ~]# cd redis-6.2.4/
[root@server3 redis-6.2.4]# cd utils/
[root@server3 utils]# ./install_server.sh
Welcome to the redis service installer
This script will help you easily set up a running redis server
Please select the redis port for this instance: [6379]
Selecting default: 6379
Please select the redis config file name [/etc/redis/6379.conf]
Selected default - /etc/redis/6379.conf
Please select the redis log file name [/var/log/redis_6379.log]
Selected default - /var/log/redis_6379.log
Please select the data directory for this instance [/var/lib/redis/6379]
Selected default - /var/lib/redis/6379
Please select the redis executable path [/usr/local/bin/redis-server]
Selected config:
Port : 6379
Config file : /etc/redis/6379.conf
Log file : /var/log/redis_6379.log
Data dir : /var/lib/redis/6379
Executable : /usr/local/bin/redis-server
Cli Executable : /usr/local/bin/redis-cli
Is this ok? Then press ENTER to go on or Ctrl-C to abort.
Copied /tmp/6379.conf => /etc/init.d/redis_6379
Installing service...
Successfully added to chkconfig!
Successfully added to runlevels 345!
Starting Redis server...
Installation successful!
[root@server3 utils]# vim /etc/redis/6379.conf
...
bind *
replicaof 192.168.56.11 6379
[root@server3 ~]# /etc/init.d/redis_6379 restart
其它redis节点依次类推
server2以此类推
(3)测试主从复制
master写入数据
[root@server1 ~]# redis-cli
127.0.0.1:6379> info
127.0.0.1:6379> set name westos
查看slave端是否同步
[root@server3 ~]# redis-cli
127.0.0.1:6379> get name
"westos"
###4.redis高可用###
Sentinel(哨兵)是用于监控redis集群中Master状态的工具,是Redis 的高可用性解决方案,sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel是redis高可用的解决方案,sentinel系统可以监视一个或者多个redis master服务,以及这些master服务的所有从服务;当某个master服务下线时,自动将该master下的某个从服务升级为master服务替代已下线的master服务继续处理请求。
sentinel可以让redis实现主从复制,当一个集群中的master失效之后,sentinel可以选举出一个新的master用于自动接替master的工作,集群中的其他redis服务器自动指向新的master同步数据。一般建议sentinel采取奇数台,防止某一台sentinel无法连接到master导致误切换。
原理:
一主两从的情况下,当master与两个slave或因网络关系断掉的情况下,客户端并不知道master失联,会持续写入数据,但此时slave端已经不能复制数据。slave会选举一个变成新的master,形成新的主从关系。
如果此时master恢复,重新加入主从关系,会转为一个新的slave,但因为超时连接,会清除自己的所有数据,那么客户端写入的数据就会丢失。
如果需要解决此问题,则需要两个slave同时认定不能连接master,或者,超过设定时间不能连接,则此时master端会拒绝客户端继续写入,那么重新接入变成slave时就不会造成数据丢失。
(1)配置
在server1主机中,配置sentinel,并复制到server2和server3中。
[root@server1 redis-6.2.4]# cp sentinel.conf /etc/redis/
[root@server1 redis-6.2.4]# cd /etc/redis/
[root@server1 redis]# vim sentinel.conf
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
logfile ""
dir /tmp
sentinel monitor mymaster 192.168.56.11 6379 2 ##master为server1,2表示需要两票通过,这台主机就被认定宕掉
sentinel down-after-milliseconds mymaster 10000 ##连接超时为10s
acllog-max-len 128
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
SENTINEL resolve-hostnames no
SENTINEL announce-hostnames no
拷贝配置文件
[root@server1 redis]# scp sentinel.conf server2:/etc/redis/
[root@server1 redis]# scp sentinel.conf server3:/etc/redis/
启动服务
[root@server1 redis]# redis-sentinel /etc/redis/sentinel.conf
其它主机直接启动服务,无需更改配置文件
[root@server2 ~]# redis-sentinel /etc/redis/sentinel.conf
[root@server3 ~]# redis-sentinel /etc/redis/sentinel.conf
(2)测试
关闭redis master
[root@server1 ~]# redis-cli shutdown
redis集群会自动切换master
当原来的master再次启动后,会以slave身份加入集群
[root@server1 ~]# /etc/init.d/redis_6379 start
[root@server1 ~]# redis-cli info
###5.redis集群###
(1)配置集群
[root@server1 redis-6.2.4]# cd utils/
[root@server1 utils]# cd create-cluster/
[root@server1 create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
[root@server1 create-cluster]# ./create-cluster create
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 127.0.0.1:30005 to 127.0.0.1:30001
Adding replica 127.0.0.1:30006 to 127.0.0.1:30002
Adding replica 127.0.0.1:30004 to 127.0.0.1:30003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: 97659fdbb23eb6885d5b8332be4732757859abe9 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
M: 61a153651897aadf57ed62e0e27789db52f4549b 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
M: 258d4258594f6c7f81f8bc18000e24aa45b08ac4 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
S: 60e4a9a86c6cea09703e7aa45cc363f142101876 127.0.0.1:30004
replicates 97659fdbb23eb6885d5b8332be4732757859abe9
S: 73083399d7e8f6374a50aaef208dd7f17b2ebde1 127.0.0.1:30005
replicates 61a153651897aadf57ed62e0e27789db52f4549b
S: d4743d579d365f335a5abead72f618212ec700d4 127.0.0.1:30006
replicates 258d4258594f6c7f81f8bc18000e24aa45b08ac4
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 127.0.0.1:30001)
M: 97659fdbb23eb6885d5b8332be4732757859abe9 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: d4743d579d365f335a5abead72f618212ec700d4 127.0.0.1:30006
slots: (0 slots) slave
replicates 258d4258594f6c7f81f8bc18000e24aa45b08ac4
M: 61a153651897aadf57ed62e0e27789db52f4549b 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 258d4258594f6c7f81f8bc18000e24aa45b08ac4 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 60e4a9a86c6cea09703e7aa45cc363f142101876 127.0.0.1:30004
slots: (0 slots) slave
replicates 97659fdbb23eb6885d5b8332be4732757859abe9
S: 73083399d7e8f6374a50aaef208dd7f17b2ebde1 127.0.0.1:30005
slots: (0 slots) slave
replicates 61a153651897aadf57ed62e0e27789db52f4549b
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
查看命令帮助
[root@server1 create-cluster]# redis-cli --cluster help
获取集群状态
[root@server1 create-cluster]# redis-cli --cluster check 127.0.0.1:30001
127.0.0.1:30001 (97659fdb...) -> 0 keys | 5461 slots | 1 slaves.
127.0.0.1:30002 (61a15365...) -> 0 keys | 5462 slots | 1 slaves.
127.0.0.1:30003 (258d4258...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: 97659fdbb23eb6885d5b8332be4732757859abe9 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: d4743d579d365f335a5abead72f618212ec700d4 127.0.0.1:30006
slots: (0 slots) slave
replicates 258d4258594f6c7f81f8bc18000e24aa45b08ac4
M: 61a153651897aadf57ed62e0e27789db52f4549b 127.0.0.1:30002
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
M: 258d4258594f6c7f81f8bc18000e24aa45b08ac4 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 60e4a9a86c6cea09703e7aa45cc363f142101876 127.0.0.1:30004
slots: (0 slots) slave
replicates 97659fdbb23eb6885d5b8332be4732757859abe9
S: 73083399d7e8f6374a50aaef208dd7f17b2ebde1 127.0.0.1:30005
slots: (0 slots) slave
replicates 61a153651897aadf57ed62e0e27789db52f4549b
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
(2)测试集群
连接集群
[root@server1 create-cluster]# redis-cli -c -p 30001 info ##-c表示操作的是一个集群,-p指定端口
在slave上写数据,数据会被重定向到slave对应的master
[root@server1 create-cluster]# redis-cli -c -p 30004
127.0.0.1:30004> set name wxh
-> Redirected to slot [5798] located at 127.0.0.1:30002
OK
关闭redis实例,集群自动切换
[root@server1 create-cluster]# redis-cli -c -p 30002 shutdown
启动redis实例,被停掉的30002会自动启动起来,此时30002变成slave
[root@server1 create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
当有一组主从同时被down,则整个集群都被down掉不可用
[root@server1 create-cluster]# redis-cli -c -p 30002 shutdown
[root@server1 create-cluster]# redis-cli -c -p 30004 shutdown
[root@server1 create-cluster]# redis-cli -c -p 30001
127.0.0.1:30001> get name
(error) CLUSTERDOWN The cluster is down
启动redis实例,集群恢复
[root@server1 create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
数据完好
[root@server1 create-cluster]# redis-cli -c -p 30001 get name
"wxh"
(3)添加节点和分片
再启动两个redis实例
[root@server1 create-cluster]# vim create-cluster
...
NODES=8
...
[root@server1 create-cluster]# ./create-cluster start
Starting 30001
Starting 30002
Starting 30003
Starting 30004
Starting 30005
Starting 30006
Starting 30007
Starting 30008
添加集群节点
[root@server1 create-cluster]# redis-cli --cluster add-node 127.0.0.1:30007 127.0.0.1:30001
添加slave节点
[root@server1 create-cluster]# redis-cli --cluster add-node 127.0.0.1:30008 127.0.0.1:30001 --cluster-slave --cluster-master-id 2cfe812f247254aa593f07bcc5e15291b77ecef6
迁移hash槽
[root@server1 create-cluster]# redis-cli --cluster reshard 127.0.0.1:30001 ##重新分配哈希槽
>>> Performing Cluster Check (using node 127.0.0.1:30001)
M: 97659fdbb23eb6885d5b8332be4732757859abe9 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
S: d4743d579d365f335a5abead72f618212ec700d4 127.0.0.1:30006
slots: (0 slots) slave
replicates 258d4258594f6c7f81f8bc18000e24aa45b08ac4
S: 61a153651897aadf57ed62e0e27789db52f4549b 127.0.0.1:30002
slots: (0 slots) slave
replicates 73083399d7e8f6374a50aaef208dd7f17b2ebde1
M: 2cfe812f247254aa593f07bcc5e15291b77ecef6 127.0.0.1:30007
slots: (0 slots) master
1 additional replica(s)
M: 258d4258594f6c7f81f8bc18000e24aa45b08ac4 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 60e4a9a86c6cea09703e7aa45cc363f142101876 127.0.0.1:30004
slots: (0 slots) slave
replicates 97659fdbb23eb6885d5b8332be4732757859abe9
S: 2cc38329498a358c6e7486bb4621017261a63db3 127.0.0.1:30008
slots: (0 slots) slave
replicates 2cfe812f247254aa593f07bcc5e15291b77ecef6
M: 73083399d7e8f6374a50aaef208dd7f17b2ebde1 127.0.0.1:30005
slots:[5461-10922] (5462 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.
How many slots do you want to move (from 1 to 16384)? 3000 ##要分出去多少哈希槽
What is the receiving node ID? 2cfe812f247254aa593f07bcc5e15291b77ecef6 ##接收节点的id
Please enter all the source node IDs.
Type 'all' to use all the nodes as source nodes for the hash slots.
Type 'done' once you entered all the source nodes IDs.
Source node #1: all ##从哪些节点取哈希槽
Ready to move 3000 slots.
Source nodes:
M: 97659fdbb23eb6885d5b8332be4732757859abe9 127.0.0.1:30001
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: 258d4258594f6c7f81f8bc18000e24aa45b08ac4 127.0.0.1:30003
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
M: 73083399d7e8f6374a50aaef208dd7f17b2ebde1 127.0.0.1:30005
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
Destination node:
M: 2cfe812f247254aa593f07bcc5e15291b77ecef6 127.0.0.1:30007
slots: (0 slots) master
1 additional replica(s)
将30007节点加入集群中,但是并没有分配slot,所以这个节点并没有真正的开始分担集群工作,所以要进行分片。重新分片基本上意味着将哈希槽从一组节点移动到另一组节点,并且像群集创建一样。
把30008节点加入到30001节点的集群中。指定masterid为30007的id,检查集群,此时30007有一个从节点。
给30007分配哈希槽(交互式)