Docker微服务-Redis分布式实现

一、3种分布式实现原理

1、哈希取余

方法:2亿条记录就是2亿个kv,我们单机不行必须要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key)%N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。

优点:简单粗暴,直接有效,只需要预估好数据规划好节点,例如3台、8台、10台,就能保证一段时间的数据支撑。使用Hash算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。

缺点:原来规划好的节点,进行扩容或者缩容就比较麻烦了额,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化: Hash(key)/3会变成Hash(key)/P?。此时地址经过取余运算的结果将发生很大变化,根据公式获取的服务器也会变得不可控。某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

hash(key)的实现:crc32()函数

        1、PHP,java,甚至Mysql等都自带函数crc32()

        2、python好像需要自己写了

2、一致性哈希算法

方法:一致性哈希算法将整个服务器模拟成0 - 2^32-1个节点,散落在一个环上,但实际不会有这么多台服务器提供服务。我们通过对key的hash计算得到一个值,并把他映射到对应的位置,如果计算的值大于了环的长度0 - 2^32-1,可以除法取余。如果映射到的节点没有机器,那么顺时针把值存到下一个节点。

优点

        1、扩展性:如果在node1和node2之间加一台机器的话node5,那一部请求会打到node5上,相当于原本存在node2的数据存到了node5上。

        2、容错性:如果node2坏了或者下掉了,原本打到node2的请求会打到node4上,只会顺时针影响一台服务器

不糊影响整个服务器的运行,只会影响一台服务器。

缺点:数据倾斜问题,比如突然增加或者减少节点,会造成下一个节点的请求突然减少或者倍增。

3、哈希槽

方法:一个集群只能有16384个槽,编号0-16383(0-2^14-1)。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key求哈希值,然后对16384取余,余数是几key就落入对应的槽里。slot =CRC16(key) %16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。槽解决的是粒度问题,相当于把粒度变大了,这样便于数据移动。哈希解决的是映射问题,使用key的哈希值来计算所在的槽,便于数据分配。

优点:解决了一致性哈希算法的数据倾斜问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。

二、实战哈希槽分布式

1、先创建6个redis容器

docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7001

docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7002

docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7003

docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7004

docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7005

docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7006

 解释几个参数

--net host 使用宿主机的IP和端口,默认

--cluster-enabled yes 开启redis集群

--appendonly yes 开启持久化

*** 非容器操作---修改配置文件

1)redis.conf 

# 如果是同一台机器启动多个redis服务,那需要配置多个redis.conf文件,需要修改如下

pidfile " /var/run/redis_7001.pid"
port 7001
dbfilename "dump7001.rdb"

# 开启集群

cluster-enabled yes

#当前节点配置文件名字
cluster-config-file nodes-7001.conf

# 设置节点失联时间,节点超过多长时间失联会进行主从切换
cluster-node-timeout15000

cluster-require-full-coverage no

如果某一段插槽的主从都挂掉,而cluster-require-full-coverage为yes ,那么,整个集群都挂掉,
如果某一段插槽的主从都挂掉,而cluster-require-full-coverage为no,那么,该插槽数据全都不能使用,也无法存储,但其它机器不受影响。

2)创建完启动6个redis

redis-server  redis.conf 

2、创建主从关系

进入第一台机器执行,其实进入哪个容器都可以的哈。执行下面命令创建集群。

redis-cli --cluster create 192.168.186.129:7001 192.168.186.129:7002 192.168.186.129:7003 192.168.186.129:7004 192.168.186.129:7005 192.168.186.129:7006 --cluster-replicas 1

 

 遇到询问输入:yes,这样就创建完成了。

--replicas 1采用最简单的方式配置集群,一台主机,一台从机,正好三组
 

*** 非容器操作---

1)redis5和redis6都集成了将多个节点配置成一个集群的机制ruby,在更低版本的redis里需要安装集群插件,这里不追溯了,安装步骤可以百度下。 

2)先进入redis的安装目录,在进入src目录,就可以执行上面容器使用的创建集群命令了。

3、查看集群信息命令

127.0.0.1:7001> cluster info

127.0.0.1:7001>cluster nodes

查看集群的主从关系 

 从上面的截图可以看出来:7001、7002、7003是master,7004、7005、7006是slave,他们的主从关系是:

7001 => 7006

7002 => 7004

7003 => 7005

redis-cli --cluster check 192.168.186.129:7001

 

4、集群链接redis

如果还像之前链接redis就会出现下面的情况有些值存储不成功

redis-cli -p 7001

 要改用集群方式链接加参数:-c

redis-cli -c -p 7001

 这样如果不在当前的槽点机器,会跳转到集群中的槽点机器。

5、主从容错切换

当集群中7001机器挂掉的时候,他的从机7006会立马上位,升级为master提供服务;但是当7001恢复的时候,他会变为从机而不是主机。但是保证了集群的高可用性。

6、扩容

a. 我们新增2台集群机器,作为第四组主从

docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7007

docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 7008

 b.将新增的7007添加到7001所在集群中

redis-cli --cluster add-node 192.168.186.129:7007 192.168.186.129:7001

c.检查下集群情况:7007没有槽位,接下来给它分配槽位。

 d. 重新给集群分配槽号

redis-cli --cluster reshard 192.168.186.129:7001

 输入完命令,会有询问:

        4096:16384/4算出来的;

        cb0a3a9f45fb4b83a589a9a8f32d96a77eea858f :是给谁分配槽位,我写入的是7007的id

        all:是给集群中的主机全部重新分配

下面还有询问,输入yes即可。这样我们就给7001分配了槽位,等分配完成。查看下分配情况:

 你会发现,7007的槽位是其他主机挪过来一部分,给他的,片段。而不是全部重新分配,也就保证了,之前在7001的数据还在7001,只是把没用到的槽位分配给了7007.这点狠重要。

e. 把7008挂到7007作为slave。

redis-cli --cluster add-node 192.168.186.129:7008 192.168.186.129:7001 --cluster-slave --cluster-master-id cb0a3a9f45fb4b83a589a9a8f32d96a77eea858f

 

 到此为止,我们扩容就完成了:4主4从

7、缩容:把7007和7008删除

a.先删除7008

命令:redis-cli --cluster del-node 集群中任意一个主机:IP端口 要删除的机器ID

redis-cli --cluster del-node 192.168.186.129:7001 97fd8daa9e20613d5f31928f0baae475961dec9a

 b.重新分配槽号

redis-cli --cluster reshard 192.168.186.129:7001

 

 c.删除7007

redis-cli --cluster del-node 192.168.186.129:7001 cb0a3a9f45fb4b83a589a9a8f32d96a77eea858f

 到此缩容完毕。

8、常用命令

1)计算key的插槽值

cluster keyslot aaa

2)统计槽位有多少个值,注意,这个命令只能查看自己服务器插槽里的值,其它看不到

countkeysinslot 4847

3)获取槽位中的keys

ysinslot 484710

9、PHP、Java操作redis集群

操作的时候直接连接redis集群即可,不用单个连接操作

10、优势和劣势

1)优势:实现扩容、分摊压力、无中心化

2)缺点:

        a、多键操作是不被支持的L

        b、多键的Redis事务是不被支持的。

        c、lua脚本不被支持

        d、由于集群方案出现较晚,很多公司已经采用了其他的集群方案,而代理或者客户端分片的方案想要迁移至redis cluster,需要整体迁移而不是逐步过渡,复杂度较大。·

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Novel-Cloud是基于小说精品屋-plus构建的Spring Cloud 微服务技术栈学习型小说项目,致力于原创文学阅读与写作,提供了爬虫工具用于开发过程中测试数据的采集。采用了时下最新的Spring Boot 2.2.5.RELEASE 、Spring Cloud Hoxton.SR4、 MyBatis3DynamicSql、Sharding-Jdbc、Redis、RabbitMq、ElasticSearch、Docker等流行技术,集成了Nacos注册中心/配置中心、Spring Cloud Gateway网关、Spring Boot Admin监控中心、ELK分布式日志分析等基础服务。前端计划使用Vue开发。 Novel-Cloud安装步骤: 1、下载源码,如果是ZIP包,下载后需要解压。 2、开发环境配置,请确保开发机器上已安装如下软件环境。  Java开发工具包jdk1.8+  IDE(Eclipse或IntelliJ IDEA)  项目管理工具maven  微服务注册中心/配置中心nacos  分布式缓存服务Redis  搜索引擎服务ElasticSearch  ElasticSearch可视化客户端Kibana  消息中间件RabbitMq  数据库服务Mysql 3、登陆nacos配置中心导入下载源码中的配置文件。 4、使用IDE导入下载的源码(这里以IntelliJ IDEA为例)。 5、修改通用配置中的配置中心地址和命名空间ID。 6、启动微服务网关。  修改网关服务的配置中心地址和命名空间ID  修改网关配置文件注册中心地址和命名空间ID  启动网关服务novel-gateway 7、启动监控服务。  修改监控服务的配置中心地址和命名空间ID  修改监控微服务的注册中心地址和命名空间ID以及登陆的用户名和密码  启动监控服务novel-monitor,启动方法和网关服务相同  访问监控服务,因为网关中配置了监控服务的路由,所以可直接或通过网关来访问监控服务:http://<网关ip>:<网关端口号>/monitor 8、启动业务微服务,这里以小说微服务为例。  修改网关配置文件book-service.yml中的注册中心地址和命名空间ID,以及其他配置(数据库/redis/elasticsearch/mq等),方法同上  启动novel-service服务,方法同上  访问接口文档:http://<服务IP>:<服务端口号>/swagger-ui.html,  例如:http://127.0.0.1:620/swagger-ui.html 9、通过网关统一接口访问路径。 http://<网关IP>:<网关端口号>/api/<接口路径> 以小说小说分类列表查询接口为例:http://127.0.0.1:527/api/book/listBookCategory 10、访问用户中心/作家中心等需要认证的接口。  访问登陆接口获取JWT  设置JWT认证  访问需要认证的接口

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值