1.并发问题
redis官方生成能够达到 10万/每秒,每秒执行10万条命令
假如业务须要每秒100万的命令执行呢?
2.数据量太大
一台服务器内存正常是16~256G,假如你的业务须要500G内存,html
新浪微博做为世界上最大的redis存储,就超过1TB的数据,去哪买这么大的内存条?各大公司有本身的解决方案,推出各自的集群功能,核心思想都是将数据分片(sharding)存储在多个redis实例中,每一片就是一个redis实例。node
各大企业集群方案:
twemproxy由Twitter开源
Codis由豌豆荚开发,基于GO和C开发
redis-cluster官方3.0版本后的集群方案
解决方案以下redis
- 配置一个超级牛逼的计算机,超大内存,超强cpu,可是问题是。。。。
2.正确的应该是考虑分布式,加机器,把数据分到不一样的位置,分摊集中式的压力,一堆机器作一件事数据库
redis3.0集群采用P2P模式,彻底去中心化,将redis全部的key分红了16384个槽位,每一个redis实例负责一部分slot,集群中的全部信息经过节点数据交换而更新。ruby
redis实例集群主要思想是将redis数据的key进行散列,经过hash函数特定的key会映射到指定的redis节点上
数据分布理论
分布式数据库首要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每一个节点负责整个数据的一个子集。服务器
常见的分区规则有哈希分区和顺序分区。Redis Cluster
采用哈希分区规则,所以接下来会讨论哈希分区规则。架构
- 节点取余分区
- 一致性哈希分区
- 虚拟槽分区(redis-cluster采用的方式)
顺序分区
哈希分区
节点取余并发
例如按照节点取余的方式,分三个节点分布式
1~100的数据对3取余,能够分为三类ide
- 余数为0
- 余数为1
- 余数为2
那么一样的分4个节点就是hash(key)%4
节点取余的优势是简单,客户端分片直接是哈希+取余
一致性哈希
客户端进行分片,哈希+顺时针取余
虚拟槽分区
Redis Cluster
采用虚拟槽分区
虚拟槽分区巧妙地使用了哈希空间,使用分散度良好的哈希函数把全部的数据映射到一个固定范围内的整数集合,整数定义为槽(slot)。
Redis Cluster槽的范围是0 ~ 16383。
槽是集群内数据管理和迁移的基本单位。采用大范围的槽的主要目的是为了方便数据的拆分和集群的扩展,
每一个节点负责必定数量的槽。
搭建redis cluster
搭建集群分为几部
- 准备节点(几匹马儿)
- 节点通讯(几匹马儿分配主从)
- 分配槽位给节点(slot分配给马儿)
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@yugo /opt/redis/config 17:12:30]#ls redis-7000.conf redis-7002.conf redis-7004.conf redis-7001.conf redis-7003.conf redis-7005.conf
#确保每一个配置文件中的端口修改!!
2.运行redis实例
建立6个节点的redis实例
1855 2018-10-24 15:46:01 redis-server redis-7000.conf 1856 2018-10-24 15:46:13 redis-server redis-7001.conf 1857 2018-10-24 15:46:16 redis-server redis-7002.conf 1858 2018-10-24 15:46:18 redis-server redis-7003.conf 1859 2018-10-24 15:46:20 redis-server redis-7004.conf 1860 2018-10-24 15:46:23 redis-server redis-7005.conf
检查日志文件
cat 7000.log
检查redis服务的端口、进程
netstat -tunlp|grep redis
ps -ef|grep redis
此时集群还不可用,能够经过登陆redis查看
redis-cli -p 7000 set hello world (error)CLUSTERDOWN The cluster is down
3.建立开启redis-cluster
准备ruby环境
- 下载、编译、安装Ruby
- 安装rubygem redis
- 安装redis-trib.rb命令
第一步,安装ruby(这些命令能够放入一个sh脚本文件里)
#下载ruby wget https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.1.tar.gz #安装ruby tar -xvf ruby-2.3.1.tar.gz ./configure --prefix=/opt/ruby/ make && make install
#准备一个ruby命令
#准备一个gem软件包管理命令 #拷贝ruby命令到path下/usr/local/ruby cp /opt/ruby/bin/ruby /usr/local/
cp bin/gem /usr/local/bin
安装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
安装redis-trib.rb命令
[root@yugo /opt/redis/src 18:38:13]#cp /opt/redis/src/redis-trib.rb /usr/local/bin/
一键开启redis-cluster集群
#每一个主节点,有一个从节点,表明--replicas 1
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
#集群自动分配主从关系 7000、700一、7002为 700三、700四、7005 主动关系
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@yugo /opt/redis/src 18:42:14]#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:10468 cluster_stats_messages_pong_sent:10558 cluster_stats_messages_sent:21026 cluster_stats_messages_ping_received:10553 cluster_stats_messages_pong_received:10468 cluster_stats_messages_meet_received:5 cluster_stats_messages_received:21026
测试写入集群数据,登陆集群必须使用redis-cli -c -p 7000必须加上-c参数
127.0.0.1:7000> set name chao -> Redirected to slot [5798] located at 127.0.0.1:7001 OK 127.0.0.1:7001> exit [root@yugo /opt/redis/src 18:46:07]#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 "chao"
集群ok
工做原理:
redis客户端任意访问一个redis实例,若是数据不在该实例中,经过重定向引导客户端访问所须要的redis实例