Redis持久化及Redis集群

2017-10-21 14:16:27来源:oschina作者:勤劳的开发者px人点击

分享
Redis特性
多数据库

Redis 内部自带有16个数据库,序号分别从0 - 15 。 默认我们操作的数据都是存放在 0 号数据库中


1. 切换数据库


select 1 选择1号数据库


2. 迁移数据到指定数据库


move key 1 从当前数据库中迁移 key到 1号数据库


如 : move myset 1


消息订阅&发布

订阅&发布需要多个客户端协同工作。 由A客户端订阅 指定频道消息、由B客户端发布 指定频道的消息 。 一般会在网络聊天室中出现、实际开发当中这个知识点比较少用到。


演示如下:


分别启动两个终端。


A终端使用:


subscribe cctv5: 意思是 ,该终端在订阅频道名为 cctv5的消息。


当然也可以进行批量订阅:


subscribe cctv* 只要频道是以cctv 打头的都进行订阅。 B 终端使用


publish cctv5 'i love china...' 发布消息


一旦B终端发布消息,那么A终端就会收到消息。


事务

Redis的事务 与关系型数据库的事务还是有一点区别的。 虽然都是包含了一组操作逻辑,但是关系型数据库是 只要这一组中有一个小动作失败,那么组内的所有逻辑都以失败告终。


Redis的却是,如果有一个小动作失败了,那么剩下的动作依然可以继续往下执行。但是Redis的事务却可以保证Redis 的服务器在没有执行完事务中的所有逻辑,不会再为其他Redis的客户端服务。也就是确保了事务不会被打断或者执行到一半的时候,突然被别的客户端插进来执行。


演示如下:


set num 10



开启事务:


multi执行逻辑1


incrby num 5


执行逻辑2


incrby num x


执行逻辑3


incrby num 10


提交事务


exec (等同于我们平常见到的 commit)


回滚事务:


discard


Redis持久化

Redis提供两种持久化方案 , 分别是 RDB 和 AOF RDB 快照 :


默认就支持的,无需配置。该机制是:在指定的时间间隔内将内存中的数据写入磁盘中。


设置持久化快照的条件


在redis.conf中修改持久化快照的条件,如下:




在redis.conf中可以指定持久化文件存储的目录



Rdb问题

一旦redis非法关闭,那么会丢失最后一次持久化之后的数据。


如果数据不重要,则不必要关心。


如果数据不能允许丢失,那么要使用aof方式。


AOF方式:


需要配置,该机制是: 以日志的方式记录服务器所处理的每一个动作。Redis服务器在启动的时候,会读取该文件来重新构建数据库,以保证启动后的数据库数据是完整的。


Redis默认是不使用该方式持久化的。Aof方式的持久化,是操作一次redis数据库,则将操作的记录存储到aof持久化文件中。


第一步:开启aof方式的持久化方案


将redis.conf中的appendonly改为yes,即开启aof方式的持久化方案。




Aof文件存储的目录和rdb方式的一样。


Aof文件存储的名称



Redis的主从复制

持久化保证了即使redis服务重启也不会丢失数据,因为redis服务重启后会将硬盘上持久化的数据恢复到内存中,但是当redis服务器的硬盘损坏了可能会导致数据丢失,如果通过redis的主从复制机制就可以避免这种单点故障,如下图:


说明:

主redis中的数据有两个副本(replication)即从redis1和从redis2,即使一台redis服务器宕机其它两台redis服务也可以继续提供服务。
主redis中的数据和从redis上的数据保持实时同步,当主redis写入数据时通过主从复制机制会复制到两个从redis服务上。
只有一个主redis,可以有多个从redis。
主从复制不会阻塞master,在同步数据时,master 可以继续处理client 请求
一个redis可以即是主又是从,如下图:


主从复制设置

主机配置


无需配置


从机配置


第一步:复制出一个从机


[root@itPX redis1]# cp bin/ bin2 –r


第二步:修改从机的redis.conf


语法:Slaveof masterip masterport


slaveof 192.168.242.137 6379



第三步:修改从机的port地址为6380


在redis.conf中修改



第四步:清除从机中的持久化文件


[root@itPX bin2]# rm -rf appendonly.aof dump.rdb


第五步:启动从机


[root@itPX bin2]# ./redis-server redis.conf


第六步:启动6380的客户端


[root@itPX bin2]# ./redis-cli -p 6380


注意:


主机一旦发生增删改操作,那么从机会将数据同步到从机中


从机不能执行写操作



127.0.0.1:6380> set s2 222

(error) READONLY You can't write against a read only slave.



Redis集群
redis-cluster架构图


架构细节:

所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽.
节点的fail是通过集群中超过半数的节点检测失效时才生效.
客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护node<->slot<->value

Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点



redis-cluster投票:容错


集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超时(cluster-node-timeout),认为该master节点挂掉.

如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。


如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态。


搭建集群
安装ruby

集群管理工具(redis-trib.rb)是使用ruby脚本语言编写的。


第一步:安装ruby


[root@itPX bin2]# yum install ruby


[root@itPXbin2]# yum install rubygems


第二步:将redis-3.0.0.gem文件上传到linux系统


第三步:安装ruby和redis接口


[root@itPX ~]# gem install redis-3.0.0.gem


第四步:将redis-3.0.0包下src目录中的以下文件拷贝到redis19/redis-cluster/


[root@itPX src]# cd /usr/local/redis19/


[root@itPX redis19]# mkdir redis-cluster


[root@itPX redis19]# cd /root/redis-3.0.0/src/


[root@itPX src]# cp redis-trib.rb /usr/local/redis19/redis-cluster


第五步:查看是否拷贝成功

搭建集群最少也得需要3台主机,如果每台主机再配置一台从机的话,则最少需要6台机器。


端口设计如下:7001-7006


第一步:复制出一个7001机器


[root@itPX redis19]# cp bin ./redis-cluster/7001 –r


第二步:如果存在持久化文件,则删除


[root@itPX 7001]# rm -rf appendonly.aof dump.rdb


第三步:设置集群参数



第四步:修改端口



第五步:复制出7002-7006机器


[root@itPX redis-cluster]# cp 7001/ 7002 -r


[root@itPX redis-cluster]# cp 7001/ 7003 -r


[root@itPX redis-cluster]# cp 7001/ 7004 -r


[root@itPX redis-cluster]# cp 7001/ 7005 -r


[root@itPX redis-cluster]# cp 7001/ 7006 –r


第六步:修改7002-7006机器的端口


第七步:启动7001-7006这六台机器



第八步:修改start-all.sh文件的权限


[root@itPX redis-cluster]# chmod u+x start-all.sh


[root@itPX redis-cluster]# ./start-all.sh


第九步:创建集群



[root@itPX redis-cluster]# ./redis-trib.rb create --replicas 1 192.168.242.137:7001 192.168.242.137:7002 192.168.242.137:7003 192.168.242.137:7004 192.168.242.137:7005 192.168.242.137:7006

>>> Creating cluster

Connecting to node 192.168.242.137:7001: OK

Connecting to node 192.168.242.137:7002: OK

Connecting to node 192.168.242.137:7003: OK

Connecting to node 192.168.242.137:7004: OK

Connecting to node 192.168.242.137:7005: OK

Connecting to node 192.168.242.137:7006: OK

>>> Performing hash slots allocation on 6 nodes...

Using 3 masters:

192.168.242.137:7001

192.168.242.137:7002

192.168.242.137:7003

Adding replica 192.168.242.137:7004 to 192.168.242.137:7001

Adding replica 192.168.242.137:7005 to 192.168.242.137:7002

Adding replica 192.168.242.137:7006 to 192.168.242.137:7003

M: 8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24 192.168.242.137:7001

slots:0-5460 (5461 slots) master

M: 4f52a974f64343fd9f1ee0388490b3c0647a4db7 192.168.242.137:7002

slots:5461-10922 (5462 slots) master

M: cb7c5def8f61df2016b38972396a8d1f349208c2 192.168.242.137:7003

slots:10923-16383 (5461 slots) master

S: 66adf006fed43b3b5e499ce2ff1949a756504a16 192.168.242.137:7004

replicates 8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24

S: cbb0c9bc4b27dd85511a7ef2d01bec90e692793b 192.168.242.137:7005

replicates 4f52a974f64343fd9f1ee0388490b3c0647a4db7

S: a908736eadd1cd06e86fdff8b2749a6f46b38c00 192.168.242.137:7006

replicates cb7c5def8f61df2016b38972396a8d1f349208c2

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.242.137:7001)

M: 8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24 192.168.242.137:7001

slots:0-5460 (5461 slots) master

M: 4f52a974f64343fd9f1ee0388490b3c0647a4db7 192.168.242.137:7002

slots:5461-10922 (5462 slots) master

M: cb7c5def8f61df2016b38972396a8d1f349208c2 192.168.242.137:7003

slots:10923-16383 (5461 slots) master

M: 66adf006fed43b3b5e499ce2ff1949a756504a16 192.168.242.137:7004

slots: (0 slots) master

replicates 8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24

M: cbb0c9bc4b27dd85511a7ef2d01bec90e692793b 192.168.242.137:7005

slots: (0 slots) master

replicates 4f52a974f64343fd9f1ee0388490b3c0647a4db7

M: a908736eadd1cd06e86fdff8b2749a6f46b38c00 192.168.242.137:7006

slots: (0 slots) master

replicates cb7c5def8f61df2016b38972396a8d1f349208c2

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

[root@itPX redis-cluster]#



连接集群


[root@itPX 7001]# ./redis-cli -h 192.168.242.137 -p 7001 –c


-c:指定是集群连接



查看集群信息



192.168.242.137:7002> cluster info

cluster_state: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:2

cluster_stats_messages_sent:2372

cluster_stats_messages_received:2372

192.168.242.137:7002>



查看集群节点



192.168.242.137:7002> cluster nodes

8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24 192.168.242.137:7001 master - 0 1451581348093 1 connected 0-5460

cb7c5def8f61df2016b38972396a8d1f349208c2 192.168.242.137:7003 master - 0 1451581344062 3 connected 10923-16383

66adf006fed43b3b5e499ce2ff1949a756504a16 192.168.242.137:7004 slave 8240cd0fe6d6f842faa42b0174fe7c5ddcf7ae24 0 1451581351115 1 connected

a908736eadd1cd06e86fdff8b2749a6f46b38c00 192.168.242.137:7006 slave cb7c5def8f61df2016b38972396a8d1f349208c2 0 1451581349101 3 connected

4f52a974f64343fd9f1ee0388490b3c0647a4db7 192.168.242.137:7002 myself,master - 0 0 2 connected 5461-10922

cbb0c9bc4b27dd85511a7ef2d01bec90e692793b 192.168.242.137:7005 slave 4f52a974f64343fd9f1ee0388490b3c0647a4db7 0 1451581350108 5 connected



jedis连接集群
设置防火墙

[root@itPX redis-cluster]# vim /etc/sysconfig/iptables

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

# Firewall configuration written by system-config-firewall

# Manual customization of this file is not recommended.

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 22 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 6379 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7001 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7002 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7003 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7004 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7005 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7006 -j ACCEPT

-A INPUT -m state --state NEW -m tcp -p tcp --dport 7007 -j ACCEPT

-A INPUT -j REJECT --reject-with icmp-host-prohibited

-A FORWARD -j REJECT --reject-with icmp-host-prohibited

COMMIT

~

~

~

~

"/etc/sysconfig/iptables" 23L, 1146C 已写入

[root@itPX redis-cluster]# service iptables restart

iptables:清除防火墙规则: [确定]

iptables:将链设置为政策 ACCEPT:filter [确定]

iptables:正在卸载模块: [确定]

iptables:应用防火墙规则: [确定]

[root@itPX redis-cluster]#



代码



使用spring

配置applicationContext.xml
























































测试代码


private ApplicationContext applicationContext;
@Before
public void init() {
applicationContext = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
}
// redis集群
@Test
public void testJedisCluster() {
JedisCluster jedisCluster = (JedisCluster) applicationContext
.getBean("jedisCluster");
jedisCluster.set("name", "zhangsan");
String value = jedisCluster.get("name");
System.out.println(value);
}

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台