当云服务融入分布式缓存系统架构,会擦出怎样的火花?

EVCache在Netflix内部是一个被广泛使用的数据缓存服务,所提供的低延迟且高可用的缓存方案可以很好地满足Netflix微服务架构需要,也用来做一般数据的存储。EVCache 能够使面向终端用户的应用,个性化算法和各种微服务都具备优良的性能。

EVCache 具有如下的特性:

分布式的键值对存储, 缓存可以跨越多个实例数据可以跨越亚马逊云服务的可用区进行复制通过Netflix内部的命名服务进行注册,自动发现新节点和服务为了存储数据,键是非空字符串,值可以是非空的字节数组、基本类型或者序列化对象,且小于 1 MB作为通用的缓存集群被各种应用使用,支持可选的缓存名称,以命名空间避免主键冲突一般的缓存命中率在 99%以上与Netflix 驻留数据框架能够良好协作,典型的访问次序: 内存 ->EVCache -> Cassandra/SimpleDB/S3

1EVCache 的CS架构

EVCache客户端是一个Java的客户端,用于发现EVCache服务器并管理所有的增删改查(CRUD)操作,由客户端处理在集群中添加/删除服务器。基于亚马逊云服务可用区,客户端在执行创建、更新和删除操作的时候复制数据。

另一方面,客户端的读操作直接从同一可用区的服务器读取数据。图2展示了EVCache 的典型部署结构和单节点客户端实例与服务器的关系。

610831753bf66d1178edf0aee682de86

图2 EVCache单节点客户端实例与服务器的关系

一个EVCache客户端连接了多个EVCache的服务器集群。 在一个区域内,Netflix有多个全数据集的拷贝,由亚马逊云服务的可用区隔离开来。虚线框描述了区域内的副本,每个拥有数据的全量镜像,作为AWS的自动伸缩组来管理这些镜像。某些缓存在一个区域内有两个镜像,有的拥有更多。这种高层架构长期来看是有效的,不会改变,每个客户端连接自己区域内所有可用区的所有服务器。写操作被发往所有实例,读操作优先选择离读请求近的服务器。

2EVCache 跨区域复制

Netflix的全球云服务遍布AWS各个服务区域,例如北弗吉尼亚、俄勒冈州和爱尔兰,为这些地区的会员提高就近服务,但网络流量会因为各种原因改变,比如关键基础设施出了问题故障,或者地区之间进行失败恢复的练习等,因此Netflix采用无态应用服务器服务于来自任何地区的会员。

这些数据如果从持久层存储获得将会非常昂贵(造成频繁的数据库访问),Netflix需要将这种数据写入到本地缓存,而且必须复制到所有地区的缓存中,以便服务于各个地区的用户请求。

微服务是依赖于缓存的,必须快速可靠地访问多种类型的数据,比如会员的观影历史、排行榜和个性化推荐等,这些数据的更新与改变都必须复制到全世界各个地区,以便这些地区的用户能够快速可靠地访问。

2daf7993a6c334f084d5d0e09d41235d

图3 EVCache 跨地域的数据复制

这张图说明复制操作是在SET操作以后实现,应用程序调用EVCache客户端库的set方法,之后复制路径对于调用者是透明的:

EVCache客户端库发送SET到缓存系统的本地地区的一个实例服务器中

EVCache客户端库同时也将写入元数据(包括key,但不包括要缓存的数据本身)到复制消息队列(Kafka)

本地区的复制中继服务将会从这个消息队列中读取消息

继服务会从本地缓存中抓取符合key的数据

中继服务会发送一个SET请求到另一个地域的复制中继服务

在另一个区域中,复制中继服务会接受请求,然后执行SET操作到它的本地缓存,完成复制在接受地区的本地应用当通过GET操作以后会在本地缓存上看到这个已经更新的数据值

这是一个简单描述,需要注意的是,它只会对SET操作有效,对于其它DELETE TOUCH或批mutation等操作不会复制,DELETE和TOUCH是非常类似的,只有一点不同:它们不从本地缓存中读取已经存在的值。

跨区域复制主要是通过消息队列进行,一个地区的EVCache客户端不会注意到其它地区的复制情况,读写都是只使用本区域缓存,不会和其它地区缓存耦合,通过消息系统来解耦合。