文章目录

  • 容量问题
  • Z轴拆分
    • 1. modula(hsah + 取模):
    • 2. random:
      • 应用
    • 3. ketama(一致性hash):
  • redis的连接成本很高
  • redis自带的拆分:cluster
    • 存取数据
  • twemproxy搭建过程
  • predixy搭建过程
  • cluster操作演示

容量问题

单机redis在使用的时候会碰到三个问题:单点故障、容量不足、访问压力。

  • 因此我们可以对redis进行AKF拆分,站在x轴的角度上可以对redis进行 主从复制 + 哨兵机制。
  • 主从复制:slave做master的全量备份保证数据的可靠性。master对外提供读写,slave对外提供读操作(读写分离),解决了部分访问压力。
  • 哨兵机制:对master做高可用,使用 哨兵集群 监控master健康状态,哨兵之间相互通信,如果发现master挂了会进行投票选举 其中一个个slave作为新的master。解决了单点故障的问题。
  • 但是由于slave是master的全量数据,在容量这个维度上来说,redis依然是一个单实例的。对于臃肿的redis实例来说,还需要对其进行y轴个z轴的拆分。

Z轴拆分

原因
Y轴拆分后某一业务的数据量还是很大,我们可以对Z轴方向上,在Client端根据 算法 继续拆分。(sharding 分片)

1. modula(hsah + 取模):

  • 这种方式是在Client增加算法逻辑,把要存入数据的进行 % 运算,后边有几个redis实例,就和几进行 % 运算,根据取模的值,把数据存入到不同的redis实例。

优点: 简单,容易操作。

缺点: 取模的值是固定的,影响分布式下的扩展性,如果添加新的redis实例会使 模数值 发生改变,再取数据的时候根据 模数 去取就无法查找到数据了。

2. random:

  • Client把数据随机放到不同的redis实例中:

应用

随机把数据放入不同的redis,取出成本很高?根本找不到数据?

如果存入的是一个list类型(lpush),key为ooxx,那么就会在两个redis中都生成ooxx的key,这个时候消费者并不是执行lpush的Client,而是执行rpop的另一个Client,都会从ooxx中取数据,无论从哪个redis取,都会取到key为ooxx的数据。这样就形成了一个类似于消息队列的功能。

3. ketama(一致性hash):

  • 在得到一个长度随机的字符串后(redis的key),经过算法得到一个等宽的其他的值(算法:hash、crc16、crc32、fnv、md5),这个值会和字符串做一个映射。
  • 和hash取模算法不同的是,一致性hash没有取模的过程(即:不会影响分布式扩展性),并且要求key和node都要参与计算。
  • 会在内存中虚拟出一个环形(哈希环)。
  • 哈希环由0 -2^32个数字组成,每一个数字都是一个点。无论后面有多少个redis实例,或新增,或减少,都会给这些redis实例一个ID号(或者IP+Port之类的)唯一标识。

优点:

  • 没有固定node数量的限制,不会造成全局洗牌。

缺点:

  • 新增节点后,造成一小部分数据无法命中。
  • 如上图,新增一个节点 node3,把node3的ID进行hash运算得到一个数值,这个数值对应 哈希环 的点 恰好在之前数据映射的点和它存入node之间(data -> node2 变为 data -> node3 -> node2), 此时如果查询data,不会从node2查询,而是会从node3里面查找data,因此查询结果为null。
  • 这种方式只适合做缓存而不适合做数据库,缓存大多为期限,即使node2里面data数据永远不会被查询到,data也会随着时间的推移而被清除掉,或者开启缓存清理策略LRU、LFU。并且node3里面无法查询到数据,可以走数据库从新缓存到node3(缓存击穿),也可以修改为从比自己大的两个node中查找数据。

扩展:虚拟节点

  • 原因
    如果node1和node2映射在哈希环的点分别在最左边和最右边,把哈希环切分成了 上半环 和 下半环,在添加数据的时候就可能出现 数据集中在某个半环上而导致 数据量的倾斜。
  • 解决
    我们可以每个node ID后面依次拼10个数字,让一个ID变成10个,用这些ID做hash运算映射到 哈希环 不同的点上,如果是两个设备在 哈希环 上面就会有20个点,这样做的目的是让一个物理设备出现在多个点上,就可以间接的解决数据倾斜的问题。

redis的连接成本很高

可以在Client和redis之间增加一个代理层(proxy),类似于Nginx这种应用层 的反向代理,基于反向代理的基础上负载均衡服务器。

  • redis自带的拆分:cluster
  • twemproxy
  • predixy

扩展
proxy是不需要记录Client状态,本身不存在数据库存储,所以proxy是无状态的 ,很容易的就可以把proxy一变多。

为了提高可用性,可以搭建LVS四层负载均衡服务器对两个proxy做负载均衡。

但是LVS也是一个单点,并且不能对后端的proxy集群做健康检查,所以可以使用keepalived建立VIP对LVS做主备HA高可用。

redis自带的拆分:cluster

规避了ketama新增redis实例时截断数据


拆分逻辑中进行预分区
redis1映射0,1,2,3,4
redis2映射5,6,7,8,9
(各领取5个槽位)。
如果redis3加入集群,会让redis1和redis2让出几个槽位,比如从redis1中拿到了3和4,在redis2中拿到了8和9(如上图)。移动数据的时候,不需要把redis全部rehash,只需要把3,4,8,9槽位的时点数据找到直接传输给redis3,redis3接收完数据后,会根据时点数据跟redis1和redis2传输期间内的数据做一个追平更新,追平的一刹那,再往3,4,8,9槽位存数据就会直接存入redis3。
Client只需要知道映射关系,就可以根据槽位正确的读取数据了

存取数据

Client想要存入k1,会随机访问redis1和redis2。可以让每个redis实例都能当家做主。k1随机进入一个redis实例后(假设这个实例是redis2),redis2会先拿k1进行hash取模算出槽位,用计算的槽位和自己的mapping映射的槽位做一个匹配,如果和自己匹配就直接存入redis2,如果不匹配再和redis2内保存的其他实例的槽位映射关系进行匹配,就能找到k1需要存的redis实例是哪个,把k1返回给Client并重定向到正确的redis实例中(假设匹配结果为redis3)。redis3拿到k1后同样要进行hash运算并且把结果和自身映射槽位进行匹配,匹配成功直接存入自己这个实例当中。

Redis 集群没有使用一致性hash, 而是引入了 哈希槽的概念。
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽.集群的每个节点负责一部分hash槽

问题: 聚合操作很难实现

操作的key都在相同的节点,可以用 hash tag 。
比如:把key设置成为{oo}k1,{oo}k2,{oo}k3这种带有{}内部有固定标识的 格式,这样在存入key的时候会使用 oo 进行取模,而不会使用k1,k2,k3进行取模。进而存入同一个redis节点。

twemproxy搭建过程

github

git clone https://github.com/twitter/twemproxy.git
yum install automake   libtool -y
cd twemproxy
autoreconf -fvi

报错:autoconf版本过低
解决办法

wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum clean all
yum install  autoconf268
cd twemproxy
autoconf268  -fvi
./configure
make
cd scripts/
cp nutcracker.init /etc/init.d/twemproxy
cd /etc/init.d/
chmod +x twemproxy
mkdir  /etc/nutcracker/
cd  twemproxy /conf
cp ./*     /etc/nutcracker/
cd  twemproxy/src
cp nutcracker  /usr/bin
cd /etc/nutcracker
cp nutcracker.yml nutcracker.yml.back
vi nutcracker.yml
service twemproxy start

nutcracker.yml


alpha:listen: 127.0.0.1:22121hash: fnv1a_64distribution: ketamaauto_eject_hosts: trueredis: trueserver_retry_timeout: 2000server_failure_limit: 1servers:- 127.0.0.1:6379:1- 127.0.0.1:6380:1

客户端直接连接22121端口
谈到集群管理不得不又说到数据的分片管理(shard),为了满足数据的日益增长和扩展性,数据存储系统一般都需要进行一定的分片,如传统的MySQL进行横向分表和纵向分表,然后应用程序访问正确的位置就需要找的正确的表。这时候,这个数据定向工作一般有三个位置可以放:

数据存储系统本身支持,Redis Cluster就是典型的试图在数据存储系统上支持分片;
客户端支持,Memcached的客户端对分片的支持就是客户端层面的;
代理支持,twemproxy就是试图在服务器端和客户端中间建代理支持;

predixy搭建过程

github

mkdir predixy
cd predixy/
wget https://github.com/joyieldInc/predixy/releases/download/1.0.5/predixy-1.0.5-bin-amd64-linux.tar.gz
cd predixy/vi predixy.conf
GENERAL模块:Bind 127.0.0.1:7617                //设置对外暴露的统一接口
SERVERS模块:Include sentinel.conf              //引入哨兵配置文件vi sentinel.conf

sentinel.conf

SentinelServerPool {Databases 16Hash crc16HashTag "{}"Distribution modulaMasterReadPriority 60StaticSlaveReadPriority 50DynamicSlaveReadPriority 50RefreshInterval 1ServerTimeout 1ServerFailureLimit 10ServerRetryTimeout 1KeepAlive 120Sentinels {+ 127.0.0.1:26379                             //三个哨兵的 IP+端口+ 127.0.0.1:26380+ 127.0.0.1:26381}Group ooxx {                     //一套哨兵可以监控多套主从,一个Group为一套主从。}                                    //Client写入的数据会被打散分别存入ooxx主从的master和xxoo主从的master。Group xxoo {}
}

配置哨兵

vi 26379.conf
port 26379
sentinel monitor ooxx 127.0.0.1 36379 2         //第一套主从ooxx的master ID+ Port,组为ooxx
sentinel monitor xxoo 127.0.0.1 46379 2         //第二套主从xxoo的master ID+ Port    组为xxoovi  26380.conf
port 26380
sentinel monitor ooxx 127.0.0.1 36379 2
sentinel monitor xxoo 127.0.0.1 46379 2vi  26381.conf
port 26381
sentinel monitor ooxx 127.0.0.1 36379 2
sentinel monitor xxoo 127.0.0.1 46379 2#启动哨兵
redis-server 26379.conf --sentinelredis-server 26380.conf --sentinel
redis-server 26381.conf --sentinel# 建立四个个文件夹36379、36380、46379、46380,分别进去启动对应的redisredis-server --port 36379
redis-server --port 46379//开启两个从机,追随对应的主机redis-server --port 36380 --replicaof 127.0.0.1 36379redis-server --port 46380 --replicaof 127.0.0.1 46379//进入代理predixy的根目录
./predixy ../conf/predixy.conf //客户端连接
redis-cli -p 7617

cluster操作演示

#自带配置
cd utils/create-cluster
vim create-cluster
./create-cluster start
./create-cluster create
redis-cli -c -p 3000./create-cluster satrt              //启动节点./create-cluster create           //创建集群
./create-cluster stop               //停止集群和节点./create-cluster clean             //清理数据文件
# 手工启动的redis实例需要在配置文件中开启 cluster-enabled yes
redis-cli --cluster create 127.0.0.1:30001 127.0.0.1:30002 127.0.0.1:30003 127.0.0.1:30004 127.0.0.1:30005 127.0.0.1:30006 --cluster-replicas 1redis-cli --cluster reshard 127.0.0.1:30001redis-cli --cluster info 127.0.0.1:30001      //随便选一个节点的ip端口redis-cli --cluster check 127.0.0.1:30001

总结:

  1. 三种搭建都是分摊redis的内存压力,将数据分到不同的redis
  2. 正常数据会分到不同节点上,不支持事务
  3. 人为干涉将数据分到同一个redis从而支持事务,watch也是一样的道理
  4. {tag}key 可以分发到同一redis支持事务

redis再战之AKF的Z轴拆分和代理集群搭建《八》相关推荐

  1. redis修改端口号后还是占用6379_Redis分布式缓存分布式集群搭建

    当你试图解决一个你不理解的问题时,复杂化就产成了.-Andy Boothe Redis集群安装部署 Redis是一个运行在内存的非关系型数据库,因为其速度快(效率高),支持数据的持久化(安全),事务操 ...

  2. Redis集群搭建很easy

    前言 哨兵模式虽然让读写分离更加高可用,但单台服务器由于本身的内存和CPU瓶颈,对于高并发和大数据业务的应用场景还是远远不能满足:对于这种情况,有点经验的小伙伴会毫不犹豫的想到集群,搞他好几个节点,负 ...

  3. redis入门及其集群搭建、哨兵模式

    一.Nosql概述 1.为什么要用Nosql 1.1 单机 MySQL 的美好时代 来源博客(https://www.cnblogs.com/lukelook/p/11135209.html) 在90 ...

  4. 【一篇入魂】redis快速入门—部署、数据类型、持久化、事务、集群

    Redis简介 简单介绍 Redis:开源.免费.非关系型数据库.K-V数据库.内存数据库,支持持久化.事务和备份,集群(支持16个库)等高可用功能.并且性能极高(可以达到100000+的QPS),易 ...

  5. Ubuntu 16.04下Redis Cluster集群搭建(官方原始方案)

    前提:先安装好Redis,参考:http://www.cnblogs.com/EasonJim/p/7599941.html 说明:Redis Cluster集群模式可以做到动态增加节点和下线节点,使 ...

  6. redis集群搭建及设置账户(转)

    Redis集群搭建以及为集群设置密码 介绍安装环境与版本 用两台虚拟机模拟6个节点,一台机器3个节点,创建出3 master.3 salve 环境. redis 采用 redis-3.2.4 版本. ...

  7. redis指定配置文件启动_深入学习 Redis 集群搭建方案及实现原理

    " 在前面的文章中已经介绍了 本文将详细介绍集群,主要内容包括: 集群的作用 集群的搭建方法及设计方案 集群的基本原理 客户端访问集群的方法 实践须知(集群伸缩.故障转移.参数优化等) 集群 ...

  8. Redis集群搭建-韩国庆

    认真一步一步搭建下来,就可以成功.... Redis-cluster集群架构讲解 redis集群专业名词称之为Redis-cluster,redis集群是从3.0版本以后才有的概念,也就是说在3.0之 ...

  9. Redis 主从集群搭建及哨兵模式配置

    Redis 主从集群搭建及哨兵模式配置 最近搭建了redis集群及哨兵模式,为方便以后查看特此记录下来: 1.Redis安装 2.主从架构 2.1 Redis主从架构图 2.2Redis主从结构搭建 ...

最新文章

  1. 莫比乌斯函数_莫比乌斯环:python-matplotlib可视化实现
  2. composer(作曲家)安装php-ml
  3. kotlin 16进制_Kotlin程序将八进制数转换为十进制数
  4. JEECG 官方微博账号
  5. Microsoft Deployment Toolkit 2008部署操作系统系列(一)
  6. cocos2dx进阶学习之屏幕适配
  7. 时域采样定理MATLAB实现
  8. CF364D Ghd(随机化)
  9. 微信 存储目录 计算机,电脑微信文件夹保存位置
  10. 图像标注的基础内容介绍
  11. 阿里云虚拟机 php $_SESSION 失效问题
  12. 在浏览器中输入网址到网页展现全部过程
  13. oracle11.2最新补丁包34386237应用手记
  14. 中国脂肪填充奶粉(FFMP)市场趋势报告、技术动态创新及市场预测
  15. 集线器、网桥、交换机、路由器
  16. 树莓派3B+ 人脸识别、摄像头安装和使用
  17. Regex:身份证号码和车牌号码正则表达式
  18. 如何在latex中加入目录,如何给目录添加超链接,以及如何去除超链接上的红色方框
  19. 新型消防建设-3D可视化消防预案综合管理平台建设方案
  20. 金融黑科技:分期付款的时候,你到底多付了多少钱?

热门文章

  1. 使用ffmpeg将avi转mp4以及yuyv转为图片
  2. {2018.5.7}荀(gou)彧(huo)同学的第二次考试小总结
  3. RV1126/RV1109芯片 人工智能安防开发板介绍
  4. 爱死磕:8月30日市场策略最高38个点!
  5. javaweb JSP JAVA 新闻发布系统源码(新闻管理系统)jsp新闻发布系统
  6. 有情人终成眷属---为好友hualex2006.12.9结婚祝福
  7. D3D12渲染技术之绘制网格
  8. TensorFlow提供Python语言的四个不同版本tensorflow,tensorflow-gpu,tf-nightly、tf-nightly-gpu
  9. Ghost Win10系统X64位和32位10041装机版下载
  10. 界面打飞机游戏,C语言