一、为什么要使用redis-cluster?

1.数据并发问题
2.数据量太大
新浪微博作为世界上最大的redis存储,就超过1TB的数据,去哪买这么大的内存条?各大公司有自己的解决方案,推出各自的集群功能,核心思想都是将数据分片(sharding)存储在多个redis实例中,每一片就是一个redis实例。 各大企业集群方案:
twemproxy由Twitter开源
Codis由豌豆荚开发,基于GO和C开发
redis-cluster官方3.0版本后的集群方案
============
解决方案:
1.一台超级计算机
2.分布式,将数据分别部署到不同的计算机。

客户端分片

redis3.0集群采用P2P模式,完全去中心化,将redis所有的key分成了16384个槽位,每个redis实例负责一部分slot,集群中的所有信息通过节点数据交换而更新。

redis实例集群主要思想是将redis数据的key进行散列,通过hash函数特定的key会映射到指定的redis节点上

数据分布理论

分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整个数据的一个子集。

常见的分区规则有哈希分区和顺序分区。Redis Cluster采用哈希分区规则,因此接下来会讨论哈希分区规则。
节点取余分区
一致性哈希分区
虚拟槽分区(redis-cluster采用的方式)
顺序分区

数据分布原理图

顺序分区

哈希分区

例如按照节点取余的方式,分三个节点
1~100的数据对3取余,可以分为三类 余数为0
余数为1
余数为2 那么同样的分4个节点就是hash(key)%4
节点取余的优点是简单,客户端分片直接是哈希+取余

一致性哈希

客户端进行分片,哈希+顺时针取余

虚拟槽分区

Redis Cluster采用虚拟槽分区

复制代码
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把所有的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。
Redis Cluster槽的范围是0 ~ 16383。
槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,
每个节点负责一定数量的槽。

二、搭建redis-cluster

搭建集群分为几部
1.准备节点(几匹马儿)
2.节点通信(几匹马儿分配主从)
3.分配槽位给节点(slot分配给马儿)
4.redis-cluster集群架构 多个服务端,负责读写,彼此通信,redis指定了16384个槽。
多匹马儿,负责运输数据,马儿分配16384个槽位,管理数据。
ruby的脚本自动就把分配槽位这事做了

官方提供通过ruby语言的脚本一键安装

1.环境准备

通过配置,开启redis-cluster

port 7000
daemonize yes
dir "/opt/redis/data"
logfile "7000.log"
dbfilename "dump-7000.rdb"
cluster-enabled yes #开启集群模式
cluster-config-file nodes-7000.conf  #集群内部的配置文件
cluster-require-full-coverage no  #redis cluster需要16384个slot都正常的时候才能对外提供服务,换句话说,只要任何一个slot异常那么整个cluster不对外提供服务。 因此生产环境一般为no

redis支持多实例的功能,我们在单机演示集群搭建,需要6个实例,三个是主节点,三个是从节点,数量为6个节点才能保证高可用的集群。每个节点仅仅是端口运行的不同!

[root@localhost opt]# ls redis-cluster/
7000.log 7004.log dump-7002.rdb nodes-7000.conf   nodes-7004.conf   redis-7002.conf
7001.log 7005.log dump-7003.rdb nodes-7001.conf   nodes-7005.conf   redis-7003.conf
7002.log dump-7000.rdb dump-7004.rdb nodes-7002.conf   redis-7000.conf redis-7004.conf
7003.log dump-7001.rdb dump-7005.rdb nodes-7003.conf   redis-7001.conf redis-7005.conf

运行实例

[root@localhost redis-cluster]# redis-server redis-7000.conf
[root@localhost redis-cluster]# redis-server redis-7001.conf
[root@localhost redis-cluster]# redis-server redis-7002.conf
[root@localhost redis-cluster]# redis-server redis-7003.conf
[root@localhost redis-cluster]# redis-server redis-7004.conf
[root@localhost redis-cluster]# redis-server redis-7005.conf
[root@localhost redis-cluster]# ps -ef|grep redis
root 9611 1 0 08:55 ? 00:00:00 redis-server *:7000 [cluster]
root 9616 1 0 08:55 ? 00:00:00 redis-server *:7001 [cluster]
root 9621 1 0 08:55 ? 00:00:00 redis-server *:7002 [cluster]
root 9626 1 0 08:55 ? 00:00:00 redis-server *:7003 [cluster]
root 9631 1 0 08:55 ? 00:00:00 redis-server *:7004 [cluster]
root 9636 1 0 08:56 ? 00:00:00 redis-server *:7005 [cluster]
root 9642 8992 0 08:56 pts/0 00:00:00 grep --color=auto redis

这时候集群还不可以用

127.0.0.1:7000> set hello world
(error) CLUSTERDOWN Hash slot not served

2.创建开启redis-cluster

准备ruby环境

下载、编译、安装Ruby

安装rubygem redis

安装redis-trib.rb命令

1.安装ruby

#下载ruby
wget https://cache.ruby-china.com/pub/ruby/ #安装ruby
tar -zxf ruby-2.3.1.tar.gz
./configure --prefix=/opt/ruby231/
make && make install #准备一个ruby命令
#准备一个gem软件包管理命令
#拷贝ruby命令到path下/usr/local/ruby
cp /opt/ruby231/bin/ruby /usr/local/
cp bin/gem /usr/local/bin

2.安装ruby gem管理包

wget http://rubygems.org/downloads/redis-3.3.0.gem
gem install -l redis-3.3.0.gem
#查看gem有哪些包
gem list -- check redis gem

3.安装redis-trib.rb

[root@yugo /opt/redis/src 18:38:13]#cp /opt/redis/src/redis-trib.rb /usr/local/bin/

4.一键开启redis-cluster

[root@localhost opt]# redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

5.查看集群状态

redis-cli -p 7000 cluster info  

redis-cli -p 7000 cluster nodes  #等同于查看nodes-7000.conf文件节点信息

集群主节点状态
redis-cli -p 7000 cluster nodes | grep master
集群从节点状态
redis-cli -p 7000 cluster nodes | grep slave
[root@localhost opt]# redis-cli -p 7000 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:1
cluster_stats_messages_ping_sent:31
cluster_stats_messages_pong_sent:38
cluster_stats_messages_sent:69
cluster_stats_messages_ping_received:33
cluster_stats_messages_pong_received:31
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:69
[root@localhost opt]# redis-cli -p 7000 cluster nodes
60b1c0a3753d9534c5521df940025a88c0188a24 127.0.0.1:7002@17002 master - 0 1614045706068 3 connected 10923-16383
2a17b7573c8c99682f353c8e1b4bc2adbff90c39 127.0.0.1:7003@17003 slave facb9aecd1c2a17d992cc9372531abbb8535d834 0 1614045703000 4 connected
facb9aecd1c2a17d992cc9372531abbb8535d834 127.0.0.1:7000@17000 myself,master - 0 1614045705000 1 connected 0-5460
d55c2ad6bbb483a4c8be560527f537a531ef2df9 127.0.0.1:7005@17005 slave 60b1c0a3753d9534c5521df940025a88c0188a24 0 1614045705000 6 connected
1ed8f68fa534e22160651545e86cc2f224b65a02 127.0.0.1:7004@17004 slave 7d9d16ab9d476bc80e407203f4d6f9d1b1bf0b9d 0 1614045707075 5 connected
7d9d16ab9d476bc80e407203f4d6f9d1b1bf0b9d 127.0.0.1:7001@17001 master - 0 1614045705062 2 connected 5461-10922
[root@localhost opt]# redis-cli -p 7000 cluster nodes |grep master
60b1c0a3753d9534c5521df940025a88c0188a24 127.0.0.1:7002@17002 master - 0 1614045723177 3 connected 10923-16383
facb9aecd1c2a17d992cc9372531abbb8535d834 127.0.0.1:7000@17000 myself,master - 0 1614045718000 1 connected 0-5460
7d9d16ab9d476bc80e407203f4d6f9d1b1bf0b9d 127.0.0.1:7001@17001 master - 0 1614045721000 2 connected 5461-10922
[root@localhost opt]# redis-cli -p 7000 cluster nodes |grep slave
2a17b7573c8c99682f353c8e1b4bc2adbff90c39 127.0.0.1:7003@17003 slave facb9aecd1c2a17d992cc9372531abbb8535d834 0 1614045731000 4 connected
d55c2ad6bbb483a4c8be560527f537a531ef2df9 127.0.0.1:7005@17005 slave 60b1c0a3753d9534c5521df940025a88c0188a24 0 1614045731224 6 connected
1ed8f68fa534e22160651545e86cc2f224b65a02 127.0.0.1:7004@17004 slave 7d9d16ab9d476bc80e407203f4d6f9d1b1bf0b9d 0 1614045729000 5 connected

6. 测试写入数据

[root@localhost opt]# redis-cli -c -p 7000
127.0.0.1:7000> set name lucas
-> Redirected to slot [5798] located at 127.0.0.1:7001
OK
127.0.0.1:7001> exit
[root@localhost opt]# redis-cli -c -p 7000
127.0.0.1:7000> ping
PONG
127.0.0.1:7000> keys *
(empty list or set)
127.0.0.1:7000> get name
-> Redirected to slot [5798] located at 127.0.0.1:7001
"lucas"

工作原理:

redis客户端任意访问一个redis实例,如果数据不在该实例中,通过重定向引导客户端访问所需要的redis实例

最新文章

  1. device host global 函数要求
  2. winform app.config文件的动态配置
  3. BeginInvoke与EndInvoke方法解决多线程接收委托返回值问题
  4. linux搭建一个配置简单的nginx反向代理服务器 2个tomcat
  5. ADO.NET中主要对象
  6. [LeetCode] Binary Tree Level Order Traversal 2
  7. Python xml
  8. linux源代码阅读笔记 八进制
  9. Swift编程语言学习12 ——实例方法(Instance Methods)和类型方法(Type Methods)
  10. C# 的sql server like 的参数
  11. [UOJ] #217. 【UNR #1】奇怪的线段树
  12. 设计模式之——工厂模式(A)
  13. CoordinatorLayout 嵌套 AppBarLayout RecyclerView ,通过代码控制,使得CoordinatorLayout 自动滑动到tab置顶的位置
  14. Ehcache缓存配置以及基本使用
  15. Elasticsearch初探(一)
  16. LeetCode 318. Maximum Product of Word Lengths (状态压缩)
  17. Animate.css介绍
  18. 利用css制作带边框的小三角
  19. 使用 Vagrant 打造跨平台开发环境fffff
  20. oracle常用函数总结(二)

热门文章

  1. bochs 调试 com 文件 magicbreak
  2. printf,sprintf,fprintf的区别与联系
  3. (转载)RTMP协议中的AMF数据 http://blog.csdn.net/yeyumin89/article/details/7932585
  4. 2019牛客多校第二场E MAZE(线段树 + 矩阵)题解
  5. SSH Keys vs GPG Keys
  6. CSS pseudo element All In One
  7. js GC & stack heap
  8. linux move file / folder bash command
  9. SVG & Blob & Base64
  10. Node.js Debugger