缓存服务器的侧缓存是什么



生活就是这样,你应该珍惜它。你应该始终是自己的主角,而不是总是在别人的戏剧中扮演配角。

我将从林语堂的《生活就是这样》中的一句话开始。

出身背景

互联网快速发展和快速演变的时代,缓存服务无疑已成为系统架构设计中不可或缺的一层。凭借丰富的数据结构、高性能的读写和简单的协议,缓存数据库可以很好地充当关系数据库的上层。为了解决节假日或高峰时段车次查询、抢票等大量数据的访问请求,长图早就引入了Redis作为数据库的上游缓存层,以缓解底层数据库的读写压力。

REDIS HA架构2014年10月,为了避免单点故障,我们尝试在生产环境的Redis主从架构中引入Redis Sentinel,以实现Redis服务的故障切换。当Redis Master主机异常停机或Redis Master服务异常崩溃时,原始的Redis Slave会自动升级为Master角色。还原原始Redis Master时,它会自动还原为从属角色。

QQ资源站

由于Redis Sentinel只能切换Redis的服务级别,无法切换IP地址,无法完全满足现有网络系统架构的需求,我们尝试在HA架构中添加一个负载平衡器设备,引用浮动IP。所有应用程序都访问浮动IP,IP地址切换由负载平衡器设备实现。

Redis Sentinel配置文件

测试总结:

主Redis服务器:redissenst-0-17

从Redis服务器:redissenst-0-18

域名

redissenst.cache.chhangtu.pvt

重新启动redissenst-0-17节点。60秒后,重新感知0-18节点成为主节点。用户访问redissenst.cache。changtu PVT域名Redis服务恢复正常。两分钟后,重新启动Redis-sent-0-17节点,并自动成为从属节点;重新启动redissenst-0-18节点。60秒后,重新感知0-17节点成为主节点。用户访问redissenst.cache。changtu pvt域名Redis服务恢复正常。两分钟后,Redis-sent-0-18节点重新启动并自动成为从属节点。

应用程序要求

通过域名统一访问缓存应用程序服务。缓存应用服务在访问Redis域名时具有断点重新连接功能。

2015年,添加了两台Redis Sentinel服务器,以管理平台上的所有Redis服务器集群。平台现有的Redis服务将进行改造,逐步升级为Redis HA架构。

CODIS分布式集群随着长图网络业务量的增加和数据量的急剧增加,Redis的单点容量受到服务器内存的限制,Redis主从架构变得无能为力。当业务系统的性能需求逐渐增加时,我们倾向于将数据存储在内存中并在本地持久化,而不是将其写入数据库。虽然SSD被用来用磁盘代替内存以获得更大的容量,但我们希望将Redis改为一种水平可扩展的分布式缓存服务?

在Codis发布之前,业内只有Twemproxy。Twemproxy本身是一个静态的分布式Redis方案,它需要很高的运维来进行容量扩展和缩减,并且很难实现平稳的容量扩展。Codis的目标是尽可能与Twemproxy兼容,并添加数据迁移功能以实现容量扩展和减少,最终取代Twemprox。本文省略了Twemproxy的介绍。

Codis使用预共享技术对数据进行分区。默认情况下,它分为1024个插槽(0-1023)。对于每个密钥,插槽ID由以下公式确定:插槽ID=crc32(密钥)%1024。每个插槽都将具有特定的服务器组ID,以指示哪个服务器组提供插槽数据。

大约在2016年6月,我们引入了Codis(当时版本是3.0,没有Redis Sentinel、Codis fe等组件。一年后,升级到3.2。本文主要使用3.0版本作为背景)。首先,我们将介绍基本环境。

系统体系结构

在公司有限的硬件资源下,我们计划部署6台服务器的Codis,这些服务器简单地分为两层,Codis代理层和Codis服务器层。

Codis代理层使用三个相对较低配置的服务器,并部署ZooKeeper、Codis Proxy、Keepalive、LVS等。三个节点是负载平衡的。Codis服务器层用于三个相对较高配置的服务器,包括SSD和三个Codis组。每个组有一个主设备和一个从设备。它是交叉部署的。每个主设备和从设备分配30G内存。

我们使用jredis编写测试程序,使用redis基准测试工具模拟压力测试(请求:1000万到10亿,并发:1000到50000,长度:固定/可变):

在性能方面,基本可以满足我们的期望。理想情况下,Codis性能值可以达到50~60K OP/S。每个codis组中的主从实例数据可以实时同步。有关详细信息,请参阅Codis高可用性群集性能测试报告_20160315。数据一致性:一方面,Codis HA不保证数据不会完全丢失。由于M-S是异步复制,当主节点异常或崩溃,并且从节点切换到主节点时,刚刚未同步的数据将丢失。另一方面,Codis支持的mget/mset命令不能保证单点的原子语义。如果mset指定KEY分布在不同的插槽上,则KEY将分布在不同机器上,从而导致成功或失败。因此,这是分布式事务的一个难点。在实际场景中,一些人还使用lua脚本来扩展Redis的功能。虽然Codis支持它,但它不能保证脚本操作的数据是否在正确的节点上执行。它仅用作转发功能。如果不能保证Lua操作的KEY在同一台机器上,Codis只能将此脚本分配给参数列表中第一个键所在的机器执行。不支持命令列表,请参阅https://github.com/CodisLabs/codis/blob/release3.2/doc/unsupported_cmds.mdRedis修改部分(增加若干说明),请参阅https://github.com/CodisLabs/codis/blob/release3.2/doc/redis_change_zh.md

倔强的青铜

于是我们组织研发同事多次分析讨论,提出了缓存服务的接口转换。经过两个多月的努力,我们取得了巨大进展,这使我们的Codis项目顺利上线。让我打断一下。让我特别感谢我们的同事王辉,他带领我们完成了公司大部分缓存服务接口转换工作。

几个改造思路

1.缓存服务分类。

对于业务缓存服务,不允许数据丢失。在现有的逻辑中,Codis和数据库将被保留并首先从Codis中读取。如果无法读取数据,将从后端数据库读取数据。对于车号和伙伴缓存服务,由于数据量大,拉取频率高的数据只能从Codis中读取。

2.修改了缓存服务的接口,增加了基本缓存服务层,并将产生的Redis/Codis相关服务包含在基本缓存服务中进行统一管理。

制定一套标准的KEY命名和管理规范,包括数据类型选择、长度、过期时间等。我们将在后台管理系统中统一公示,限制新数据的规则,限制所有不规范行为。在基本缓存服务层,一些Codis不支持的命令被重写,以标准化Redis/Codis的日常操作。热数据的统计、热数据的维护以及基本缓存服务层上的二级缓存作为热数据的快速通道的假设。

3.插槽分配

哈希算法

Codis使用预共享技术对数据进行分区。默认情况下,它分为1024个插槽(0-1023)。对于每个密钥,插槽ID由以下公式确定:SlotId=crc32(密钥)%1024。例如,pub_cty_根据算法,ct018的值为997

有趣的整改

在多年的迭代演进过程中,维护团队数次推动缓存服务架构的升级和优化,缓存服务逐渐得到改善和稳定。记录了一些“有趣”的纠正措施,供您参考。

热点数据

缓存热点数据的统计信息。假设基本缓存服务层上的二级缓存。作为热点数据的快速通道,它具有动态访问、访问速度快、变化少的特点。

根据缓存服务的主键和次键关系使用索引_{主键}方法用作管理主键和子键之间关系的SortedSet集合。统计数据的使用频率用于提取Top100数据作为热数据。分析这批数据,并根据数据的更改频率确定内存中这批数据缓存的持续时间。

二级缓存设计

缓存数据列表生成和维护

内存缓存数据的密钥列表由缓存服务生成和维护。按键列表由后台手动配置(例如,10个按键)和根据使用热量生成的系统(例如,20个按键)组成。缓存管理器的jar包只负责使用这些数据。Codis的前20位和后台手动配置的相关数据是通过预定任务获得的。在此期间,应保证所获得数据的有效性。

在本地内存中维护数据

内存缓存的自然统计数据:使用sortedSet集合计算获取每个主键下所有键的次数,并将它们汇总为记分_{主键}方法的集合。使用ZIncrby命令统计相应子键的次数,最后汇总每个主键以统计Top100的键。使用zuonionstore命令汇总信息统计信息,作为内存缓存的基础。此集合中的数据是从内存中获得的。

管理类内存缓存:分析和统计项目主进程的关键基础缓存数据并将其保存在内存中,确保相应区域的数据采集和缓存时间,并在离开数据源后最大化CTN的功能。

当发生手动更新时,存储器中相应的主键将被更新

更新发生时,由后台启动。缓存服务将标志位放在Codis中。每个客户端都获得调度任务中的标志位。如果标志位(cache_memory_update_flag)为Y,则清除内存和密钥规则表,并在下一个更新周期到来时检索数据。

总结经过半年多的时间测试和缓存服务接口转换,2016年9月,国庆节前夕,我们的Codis3.0上线了。在车辆号码查询方面,我们有了质的飞跃,特别是在节假日或高峰时段,我们在平滑扩展、数据迁移和高可用性方面表现出了巨大的优势。

三个代码_代理节点的平衡:

一年后,从2018年8月到9月,我们将Codis升级到3.2,从之前的6台服务器升级到7台。事实上,还有一个额外的Codis web节点,它独立于Codis fe、Codis dashboard和其他组件。Redis Sentinel、Codis fe等组件的引入为运维人员解决了很多问题。我不会在这里描述它们,但你可以参考那些感兴趣的人。

https://github.com/CodisLabs/codis/blob/3.2.2/doc/tutorial_zh.md

目前,Codis作为CTN的核心缓存层,一直在一如既往地提供稳定的输出,肩负着神圣的使命!

© 版权声明
THE END
喜欢就支持一下吧
点赞5赞赏 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容