我们都知道,在Web服务中,缓存技术Memcache主要用来缓存数据库的数据,减少数据库的 压力以提高性能。也有业务会存储一些临时数据进行命中的判别。
虽然Memcache兼容性很好,同时支持linux和windows平台,读写延迟也优于Redis,但是不支持持久化存储。一旦宕机,就会面临数据库压力徒增,Memcache集群重新哈希,数据恢复也需要一定的时间。如果业务做Memcache主备集群双写,那不但增加了开发成本,同时也增加了服务处理延迟。
在这样的背景下,我们寻求Memcache是否有更好高可用技术能解决以上的问题。调研了repcached+Magent和Mcrounter技术之后,Mcrouter以廉价的运维成本,50亿请求/ 秒的高性能数据,丰富的路由策略和活跃的用户社区胜出。下面就简单和大家介绍一下,Mcrouter的功能原理和在小米的使用场景。
Mcrouter特性
Mcrouter是一个Memcache协议的路由器。由于任何要接入Memcache服务的客户端,都会使用标准ASCII编码的Memcache协议,我们可以采用Memcache的通用API作为通信方式(参看下图)。对于Memcache客户端,Mcrouter完全像一个Memcache服务器。对于服务器,Mcrouter完全像一个普通的Memcache客户端。但Mcrouter丰富的可配置性,使得它更像一个简化的proxy。
下面列举了一些Mcrouter的特性。其中destination指Memcache主机(或者其他能兼容Memcache协议的缓存服务实现)。pool指集群化的destinations,并能通过配置将负载均衡分配给不同的 destination。例如,可通过hash方式均衡,亦可通过冗余数据均衡(读操作)。无论何种方式,pools最终都能以集群的方式进行管理。
支持标准开源的Memcache ASCII编码协议。
连接池:Mcrouter能让客户端共享连接池,以减少连接个数。
多种散列方法:
(1)consistent hashing算法(furc_hash),算法允许给多个Memcache实例分配哈希值,降低单机宕机对集群的影响,同时防止热点;
(2)Hostname hashing再根据分配的哈希值为客户端选择一个独一无二的副本,保证副本的高可用。
前缀路由:Mcrouter可以根据key前缀把客户端分配到不同的Memcache池。比如,你可以把以foo"为前缀的所有key分配到一个 foo"池,把以"bar"为前缀的所有key分配到另外一个"bar"池,其他的key都分配到"wildcard" 池。这是一种简单的均衡负载的方法。参照下图:
Memcache池备份:在多个主机上保存一份相同数据的备份。写操作时向所有的主机写入同一份数据,但是做读操作时只从客户端对应的缓存区读取一份数据。这样就可以处理机器系统限制造成读操作失败问题;而且当一份备份坏掉可以故障自动转移,而不会影响其正常操作。
演示路径跟踪:在测试新缓存设备时,能够路由从客户端到缓存设备的所有可能路径是非常有用的。 Mcrouter支持灵活的跟踪配置,通过重新哈希值范围跟踪测试不同大小的Memcache池,或只跟踪哈希值范围的一部分,或在运行时动态修改跟踪环境。
热加载:Mcrouter监控它所有的配置文件。一旦检测到任何配置文件被修改,Mcrouter的一个后台线程将自动的重新加载,分析这些文件。在这个操作完成之后,Mcrouter会根据新配置来处理新请求。这个过程对客户端而言是透明的。
灵活的路由方式:" 路由句柄"是由小路由模块组合而成,这些路由模块公用一个接口(路由一个请求,返回一个回复),也可以自由组合。单个路由句柄更容易理解、创建和测试。利用路由句柄创建复杂的逻辑。比如:名为"all-sync"路由句柄是由多个子句柄组成的,它发送一个请求给所有的子句柄,只有在所有的子句柄发回回复时,"all-sync"才发回其中的一个回复。还有其他的类似的例子:"all-async"(发送请求到所有的子句柄,但不会等待子句柄的回复),"all-majority"(舆论调查),"failover"(顺序的发送请求到每个子句柄直到收到一个无错误的回复)。通过"cold cached warmup"句柄能快速扩充一个Memcache池(把旧的Memcache服务器作为"暖缓存")。
Destination心跳检测和自动故障转移:Mcrouter 能够检测每个后端Memcache实例的心跳。一旦Mcrouter将一个后端Memcache实例标记为无响应,它将直接将所有的请求转移到另一个可用的Memcache实例。同时,后台形成将向无响应Memcache实例发送心跳请求,只要Memcache实例的心跳恢复正常,Mcrouter 将会重新启用这个Memcache。
在标记无响应的时候还会区分"软错误"和"硬错误"。 "软错误"(比如:数据超时)允许连续发生多次,但是一旦发生"硬错误"(比如:拒绝连接)Mcrouter立即将该Memcache标记为无响应。整个故障处理和恢复过程对客户端完全是透明的。
自动填充新增缓存:Mcrouter通过指定的"warm"缓存区主动填充新增的缓存区域的方式来消除新增缓存区造成的性能影响。
广播操作:通过在请求关键字里面增加一个特殊的前缀,能够很容易把请求备份到多个Memcache池或者集群里面。
可靠的删除操作:在一个有求必应的缓冲区里,保证所有的删除操作都送到目的地是非常重要的。Mcrouter将所有的删除操作都记录到硬盘上以防止由于网络中断或者原因导致Memcache 实例不可访问。当连接修复之后,Mcrouter将启动一个单独的进程异步的重新执行这些删除操作。这个过程对客户端是透明的,并且客户端接受到的操作结果通常是成功的。
支持多集群:Mcrouter能通过的简单的配置管理大的多集群。单个配置通过命令行参数分发到所有的集群,Mcrouter根据命令行参数的位置解释配置。
丰富的stats和debug命令:Mcrouter通过"stats"命令导出很多的内部计数器(或者以JSON格式导出到文件系统)。Mcrouter提供自我调试命令,这种命令能够反应在运行时一个特定的请求被分配到哪一个主机。
保障服务质量:Mcrouter允许以主机,池或者集群为单位设置任何请求(比如:get/set/delete)的速率的阀值,当请求个数超过阀值,剩下的请求将会被拒绝。同事也支持限制请求的速度以减缓请求的发送速度。
分割数据块:当传入的数据超过Memcache slab的大小,Mcrouter能根据slab的大小自动分割或重组数据块。
多级缓存:Mcrouter支持本地/远程缓存设置。请求数据时先从本地缓存区查找,如果在本地缓存区查找失败再从远程缓存区查找,如果在远程缓存区找到该数据,Mcrouter会自动的将数据缓存到本地缓存区。
支持IPv6:在Facebook,Mcrouter支持IPv6。同样,在Faceboo局域网以外的地方,Mcrouter也支持IPv6。
支持SSL:Mcrouter就支持双向SSL(输入或者输出),只要客户端或者目标主机其中的一方支持SSL即可。串联多个Mcrouter,在两两Mcrouter之间的连接支持SSL也是可能的。
多线程架构:Mcrouter通过一个内核一个线程的方式充分利用多核系统的优势。
Mcrouter和Xcache-client高可用测试
针对目前小米产品线java客户端普遍使用的Xcache-client,进行了Mcrouter兼容性和高可用测试。首先Xcache-client会配置多个Mcrouter后端进行流量分配,Mcrouter配置5个Memcache实例做数据hash散列和数据热备。
Mcrouter和Xcache-client 哈希一致性算法验证
用途:现有Memcache业务无缝切换到Mcrouter。
测试过程:对比新增Mcrouter前后,同样一条数据是否会选择同个Memcache节点进行读写。
测试结果:不符合预期。Mcrouter和Xcache-client 的哈希一致性算法不一致。
Memcache用户切换到Mcrouter后对于已经存入的旧数据会有一定的命中失败,新写入数据命中正常。推荐新业务和缓存数据失效时间短的业务进行迁移。
Mcrouter和Xcache-client 负载均衡验证
用途:多级负载均衡,消除Mcrouter和Memcache热点。
测试过程:随机生成一些key,测试Xcache-client到多个Mcrouter读写流量均衡;Mcrouter后端Memcache读写均衡。
测试结果:基本符合预期。数据经过Xcache-client打到Mcrouter机器上比例41:59,基本满足负载均衡的要求;
Mcrouter的写流量平均分配到后面5台Memcache机器上;读流量因为Mcrouter自身会缓存一部分数据,Memcache单机间会有10%的流量差距。存储数据会根据单个Key大小有10%~20%的内存开销差距。
Mcrouter和Xcache-client failover机制验证
用途:多级failover机制验证,消除服务单点。
测试过程:Xcache-client 的健壮性,在一个Mcrouter实例宕机后会到下个Mcrouter读取数据;Mcrouter多副本功能验证,一个Memcache挂掉,能到另外一个Memcache副本中读取数据。
测试结果:符合预期。停掉一个Mcrouter实例之后,客户端仍然能获取到数据;停掉一个主Memcache实例,客户端仍然可以获取到数据。
应用案例
小米某产品线Memcache集群迁移。中间评估过迁移Mcrouter的数据损失在5分钟之内可恢复,果断在凌晨流量低峰时段上线Mcrouter。在Mcrouter上配置了写新老集群,读老集群(Replicated pools)。等老集群旧数据过期,新老集群的数据存储量一致,再将读流量切至新集群。观察一段时间后读写流量从老集群下线。全程Mcrouter热加载,无流量损失,服务无感。
小米某产品线上线Mcrouter解决数据热备和流量负载高的问题。
双机房配置Memcache双活集群,配置3台Mcrouter进行弹性扩容和机房间自由调度。吞吐能力由之前1000cps * 5,提升至25000cps * 3,性能提升了15倍。
后续开发
分析业务的热Key,在Mcrouter上配置热Key分离,对于高吞吐和高流量的业务区分集群使用。
Mcrouter对Memcache弹性调度实例支持,动态加载到Memcache池。
文献引用:
https://code.fb.com/core-data/introducing-Mcrouter-a-Memcached-protocol-router-for-scaling-Memcached-deployments/
本文转载自微信公众号小米运维,由编码之道编辑整理
免责声明:内容来自用户上传并发布,站点仅提供信息存储空间服务,不拥有所有权,本网站所提供的信息只供参考之用。