Redis集群方案

前段时间搞了搞Redis集群,想用做推荐系统的线上存储,说来挺有趣,这边基础架构不太完善,因此需要我们做推荐系统的自己来搭这个存储环境,就自己折腾了折腾。公司所给机器的单机性能其实挺给力,已经可以满足目前的业务需求,想做redis集群主要有以下几点考虑:

1、扩展性,scale-out,以后数据量变得很大之后,不至于推到重来,redis虽然可以开启虚拟内存功能,单机也能提供超过物理内存上限的容量,但频繁在内存和硬盘间swap页会大大降低其性能,有点儿违背redis的设计初衷。

2、redis是一个单线程io复用的结构,无法有效利用服务器的多核结构,如果能在一台多核机器起多个redis进程,共同提供服务,效率会更高一些。

3、主从,数据备份和容灾。。

因此计划做的redis集群希望可以实现以下功能:

1、data sharding,支持数据切片。

2、主从备份,主节点写数据,主和从都提供读请求服务,并且支持主从自动切换。

3、读请求做负载均衡。

4、更好地,支持节点failover,数据自动迁移。

下面是前后经历的一个过程:

【第一步】尝试官方方案

肯定想去查看一下redis的官方集群方案,但是很遗憾,官方对cluster的声明如下:

Unfortunately Redis Cluster is currently not production ready, however you can get more information about it reading the specification or checking the partial implementation in the unstable branch of the Redis GitHub repositoriy.

Once Redis Cluster will be available, and if a Redis Cluster complaint client is available for your language, Redis Cluster will be the de facto standard for Redis partitioning.

Redis Cluster is a mix between query routing and client side partitioning.

由于这边想做生产环境部署,unstable branch目前还是不敢用,在官方目前的版本上做提前开发又没有资源和时间,因此就放弃了。

【第二步】初步设想的方案

舍弃了官方的方案后,就想能不能自己搭一个,当时初步的想法是:用lvs做读请求的负载均衡,在客户端代码里自己写一个一致性hash算法做数据切片,配置redis主从,并且配置keepalived做主从自动切换。这个方案应该可以施行的,但当时自己遇到一些细节方面的问题,就在stackoverflow上问了一下,问题如下:

Since the redis cluster is still a work in progress, I want to build a simplied one by myselfin the current stage. The system should support data sharding,load balance and master-slave backup. A preliminary plan is as follows:

  1. Master-slave: use multiple master-slave pairs in different locations to enhance the data security. Matsters are responsible for the write operation, while both masters and slaves can provide the read service. Datas are sent to all the masters during one write operation. Use Keepalived between the master and the slave to detect failures and switch master-slave automatically.

  2. Data sharding: write a consistant hash on the client side to support data sharding during write/read in case the memory is not enougth in single machine.

  3. Load balance: use LVS to redirect the read request to the corresponding server for the load balance.

My question is how to combine the LVS and the data sharding together?

For example, because of data sharding, all keys are splited and stored in server A,B and C without overlap. Considering the slave backup and other master-slave pairs, the system will contain 1(A,B,C), 2(A,B,C) , 3(A,B,C) and so on, where each one has three servers. How to configure the LVS to support the redirection in such a situation when a read request comes? Or is there other approachs in redis to achieve the same goal?

Thanks:)

有个网友给了两个建议:

You can really close to what you need by using:

twemproxy shard data across multiple redis nodes (it also supports node ejection and connection pooling)

redis slave master/slave replication

redis sentinel to handle master failover

depending on your needs you probably need some script listening to fail overs (see sentinel docs) and clean things up when a master goes down

这位网友的两个建议挺启发的,我在看redis的官方doc的时候,对twemproxy有一些印象,但当时没有太在意,至于后者用redis sentinel做master failover,redis sentinel也是一个redis正在开发中的模块,我不太敢用。

另外,我舍弃自己的这个初步方案还有两个原因:

1、自己在写客户端data sharding和均衡服务的时候,发现实际需要考虑的问题比开始想的要复杂一些,如果写完,其实相当于将twemproxy的功能做了一遍,造轮子的事情还是少干。

2、功能做得有些冗余,一次读请求要经过客户端的sharding、然后还有经过lvs再到实际的服务器,不做优化的话,会增加不少延迟。

【第三步】最终的方案,如下图所示

图中画的挺明白了,就不再多解释了。

twemproxy是twitter开源的一个数据库代理服务,可以用于memcached和redis的sharding,兼容二者的标准接口,但是对于redis的keys,dbsize等命令不支持,这个其实想一下也就明白了,这种pool内跨机做统计的命令proxy一般不会支持的。另外,twemproxy在自身与后台redis之间使用pipeline发送命令,因此性能损失比较小。但是,twemproxy对于每一个客户端连接开启的mbuf有限,最大可以设置为64k,如果在客户端代理层与twemproxy之间也使用pipeline,这个pipeline不能太深,而且不支持pipeline的原子性(transaction),其实,这个时候,相当于客户端连接与redis数据库之间存在两层pipeline,分别是客户端到twemproxy的pipeline,和twemproy到后台redis服务器的pipeline,由于二者buffer深度不一致,因此不支持pipeline的transaction也就好理解了。在引入了twemproxy,插入大规模数据的时候,有时候确实挺耗时,而且pipeline不保证原子性,丢数据时的恢复问题在客户端需要进行额外关注。

上面的结构,将读操作的负载均衡放到了客户端代码来做,写操作控制也在客户端层的代码里,另外,对于twemproy单点、主从之间可以引入keepalived来消除单点和故障恢复。

 
 

Redis集群方案的更多相关文章

  1. Redis集群方案介绍

    由于Redis出众的性能,其在众多的移动互联网企业中得到广泛的应用.Redis在3.0版本前只支持单实例模式,虽然现在的服务器内存可以到100GB.200GB的规模,但是单实例模式限制了Redis没法 ...

  2. Redis集群方案怎么做?大牛给你介绍五种方案!

    Redis集群方案 Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促使集群的发展,各个公司也在收集适合自己的集群方案,目前行业用的比较多的是下面几种集群架 ...

  3. 大厂们的 redis 集群方案

    redis 集群方案主要有两类,一是使用类 codis 的架构,按组划分,实例之间互相独立: 另一套是基于官方的 redis cluster 的方案:下面分别聊聊这两种方案: 类 codis 架构 这 ...

  4. Redis集群方案怎么做?

    转载自:https://www.jianshu.com/p/1ecbd1a88924 Redis集群方案 Redis数据量日益增大,而且使用的公司越来越多,不仅用于做缓存,同时趋向于存储这块,这样必促 ...

  5. Redis集群方案总结

    Redis集群方案总结 Redis集群方案总结Codis其余方案Redis cluster 目前,Redis中目前集群有以下几种方案: 主从复制 哨兵模式 redis cluster 代理 codis ...

  6. Redis 集群方案介绍

    由于Redis出众的性能,其在众多的移动互联网企业中得到广泛的应用.Redis在3.0版本前只支持单实例模式,虽然现在的服务器内存可以到100GB.200GB的规模,但是单实例模式限制了Redis没法 ...

  7. Redis集群方案收集

    说明: 如果不考虑客户端分片去实现集群,那么市面上基本可以说就三种方案最成熟,它们分别如下所示: 系统 贡献者 是否官方Redis实现 编程语言 Twemproxy Twitter 是 C Redis ...

  8. 基于Twemproxy的Redis集群方案(转载)

    原文地址:基于Twemproxy的Redis集群方案 概述 由于单台redis服务器的内存管理能力有限,使用过大内存redis服务器的性能急剧下降,且服务器发生故障将直接影响大面积业务.为了获取更好的 ...

  9. Redis集群方案(来自网络)

    参考: https://www.zhihu.com/question/21419897 http://www.cnblogs.com/haoxinyue/p/redis.html 为什么集群? 通常, ...

随机推荐

  1. 第19章 解释器模式(Interpreter Pattern)

    原文 第19章 解释器模式(Interpreter Pattern) 解释器模式 导读:解释器模式,平常用的比较的少,所以在写这个模式之前在博客园搜索了一番,看完之后那叫一个头大.篇幅很长,我鼓足了劲 ...

  2. js 正则学习小记之匹配字符串优化篇

    原文:js 正则学习小记之匹配字符串优化篇 昨天在<js 正则学习小记之匹配字符串>谈到 个字符,除了第一个 个,只有 个转义( 个字符),所以 次,只有 次成功.这 次匹配失败,需要回溯 ...

  3. .net中的设计模式---单例模式,涉及lock的用法

    .客户端代码 static void Main(string[] args) { Singleton singleton2 = Singleton.GetInstance(); Singleton s ...

  4. crawler_爬虫分布式设计图收集_01

  5. 插件式Web框架

    转载构建高性能插件式Web框架 基于MVC插件模式构建支持数据库集群.数据实时同步.数据发布与订阅的Web框架系统.如下图: 1.基于插件式开发 采用插件模式开发的优点是使得系统框架和业务模式有效地进 ...

  6. Linux报too many open files的解决方案

    今天系统中有一台服务器出现异常,有时连简单的shell命令都无法执行,各种奇怪的报错,有的时候又可以成功执行 如: -bash: error while loading shared librarie ...

  7. 搭建一个三台服务器的Memcached集群

    关于memcached的基础知识可以查看博客其他博文,这里只记录了搭建的过程,谢谢! 1.分别在三台服务器上安装Memcached并启动 第一.由于memcached是基于libevent的事件处理, ...

  8. 枚举 UIButton补充

    一.URL 1.什么是URL? URL是某个资源的唯一路径,通过这个路径就能访问对应的资源 2.URL的组成 协议头://全路径 * 协议头就代表资源的类型,比如http代表网络服务器资源,ftp代表 ...

  9. C# 调用Webservice并传递序列化对象

    原文:C# 调用Webservice并传递序列化对象 C#动态调用WebService注意要点 1.动态调用的url后面注意一定要加上?WSDL   例如:string _url = "ht ...

  10. C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com

    原文:C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | IT宅.com C语言语法笔记 – 高级用法 指针数组 指针的指针 二维数组指针 结构体指针 链表 | I ...