今天我们来聊聊“阿里云内存数据库Tair”。让我先自我介绍一下。我的本名是朱国云,小名宗代。2008年加入阿里巴巴,在阿里主要从事存储数据库相关,包括文件存储、缓存、内存数据库等。最开始参与阿里云飞天操作系统的研发,后来成为主要负责Tair的研发工作。一、Tair的发展历程接下来正式进入Tair相关交流。整体包括Tair的发展历程、主要节点、技术难点和相关实践。我们来看看“Tair的历史与发展”,可以看到下图:Tair的历史与发展2009年,Tair1.0在淘宝孵化。2014年到2015年,阿里云刚起步的时候,淘宝的一些基础服务和阿里云集成了,所以阿里云也提供了云缓存服务,包括CloudMemcache和CloudRedis。从Tair1.0到Tair2.0,两者最核心的区别在于一个是纯KV,一个兼容Redis。2018年,阿里有很多高度连接的数据场景,比如数据存储、查询和计算。TairGraph就是在这个过程中诞生的。2019年之后,我们把Tair的这些能力推到了公有云上。其中,Tair包含在CloudRedis中,这个版本是Tair3.0。今年我们在阿里云上分离了Tair产品,客户可以直接购买和管理Tair产品。在与客户交流时,他们有一个常问的问题:Tair的系统为什么能用13年?从淘宝时代诞生的系统和产品,到今天阿里巴巴内部还在大规模运作的其实还是比较少的,Tair就是其中之一。当然,也有很多的系统迭代和架构演进。接下来我们看一下Tair在阿里内部的应用。现在在阿里集团内部,BU的大部分核心线上业务都使用了Tair,包括最开始的淘宝和天猫电商的交易导购广告,菜鸟的电子面单物流配送轨迹,钉钉的消息。推送,优酷的视频播放列表等,这些在线业务都使用了Tair。现在在一些面向TP的在线业务场景中,业务的主要核心依赖于Tair加数据库。Tair在这里的核心定位是承载超大流量和高速存储,而不仅仅是缓存。许多企业直接将其用作内存存储。从上面我们可以了解到,Tair支持了阿里大部分的项目,并不断优化。在这个过程中,Tair也遇到了很多技术上的挑战。接下来,我们来看看Tair发展过程中的重要节点和里程碑。技术挑战。2.Tair的重要节点及技术挑战2.1重要节点淘宝电商交易刚起步时,与现在的系统架构相比,当时的业务架构比较简单。在Tair诞生之前,我们有一个内部的TDBM系统,它是一个独立的、独立的缓存服务,容量有限,访问也有限。最重要的是它是单点的,高可用是没有的。于是在2009年,开发了Tair1.0。Tair1.0是一个独立的分布式缓存服务,它是集群模式,完全实现了节点的扩容和缩容,这一点有别于TDBM系统。Tair1.0形成基本技术架构后,Tair也以此路线为基础演进了很多年。随着移动互联网的诞生,整个应用场景变得更加丰富。电子商务越来越繁荣,搜索广告被推荐越来越多,社交网络的兴起,手游的发展,LBS的应用,在这些行业的在线场景中,对缓存和高速的需求存储系统越来越多从下图可以看出,Tair1.0也在伴随着这些行业不断演进和发展。数据量的增加对Tair的内存存储提出了新的挑战,如何低成本解决面向互联网的在线数据的存储和查询。由于SSD固态硬盘的成熟,Tair基于SSD存储介质实现了TairLDB持久化存储引擎,提供了高性能大容量的解决方案。2018年之后,持久内存和新存储介质的出现也给Tair提供了新的进化契机。总体来说,现阶段Tair已经从1.0的缓存定位逐渐进化为NoSQL存储系统。在接口层面,也从最简单的KV接口进化到提供更复杂、更丰富的数据接口。那么Tair的技术架构是怎样的呢?当时是典型的架构:SDK、管理节点、数据DB节点。集群内部使用了一致的类哈希算法,通过哈希将数据拆分成多个分片。同时通过主从机制实现数据DB节点的高可用。整个系统除了数据流,还有一整套Tiddos来完成系统管理。比如宕机的自动切换,集群扩缩容后数据的自动迁移和均衡。另外,你也可以选择有Proxy的架构。Proxy可以实现访问聚合、连接收敛、QueryCache等更高级的功能。图中右边其实是一个单独的DB进程,它是一个统一的服务技术框架,可以在里面支持多个存储引擎。比如我们最初定义的Tai1.0MDB就是一个KV内存。上面的流程框架完全一样,下面的存储引擎可以替换。2.2技术挑战接下来我讲讲阿里集团这几年我们面临的三个技术挑战,即阿里集团的单元化、热点、性能和成本。技术挑战-UnitizationUnitization这个项目其实是很有野心的,就是从整个应用层开始,到中间件,比如MQ,TTDL层,再到Tair和数据库层。Tair当时的三大块包括MDB、RDB、LDB。对于MDB,我们将其用作缓存。所以在做单元化的时候,并不会主动去做数据同步。而是数据库层进行数据同步,然后去另外一个单元做反向失效。对于RDB和LDB,很多业务都是作为数据的最终存储,所以我们针对这两大块做了自己的数据同步方案。这里比较难的问题是,如何保证在源头写的东西能在目的地快速消费?这个问题会和source的写入速度,destination的消费速度,两个集群的机房距离,网速有关。一是做好容量规划,二是对进程多做batch和merge处理,流式发送。另外,我们的任何系统,尤其是在线处理,都没有办法保证不出问题。无论是新发布的版本,还是很久以前触发的bug,往往都很难定位。它可能不会在几分钟或半小时内定位。这时候流量可以快速切换到另一个机房,对整体业务基本没有影响。这也是单元化带来的一个非常大的好处。技术挑战——热点2016年双十一的一个插曲,我们泰尔的一台机器,流量特别大,最高达到70%+左右。这台服务器的QPS当时是每秒几十万次,但是数值大小非常高。大的。在当时看来是一款火爆的手机产品,也是当年双十一最火的单品之一。它的访问量最大,所有的流量都去了一个服务器。到时候就顺利过去了。如果访问量大,流量大,那么服务器流量可能真的会达到很高的水位,影响稳定性。目前,大多数存储系统和数据库系统都只能从单个节点访问一段数据。这个问题其实是不可避免的。但是,单个数据节点的访问量很大,造成这种现象的原因有很多。比如有热点商品查询,或者死循环的商务文案。这些可能会导致某个节点的访问量特别大。当年的双十一,Tair最新的SDK竟然有本地缓存??的功能,可以通过push来开启。但是,有的业务已经升级到新版TairSDK,有的还没有升级,难以一一掌控。这也是复杂系统和应用后的普遍现象,很难保证版本统一。同时,SDK端的本地缓存占用了应用服务器的资源,内存非常宝贵。这个缓存可能会对业务产生影响。由于SDK端的解决方案不是最合适的,我们考虑通过服务端解决。最后讨论的解决方案是在每个DB节点上开辟一个热点区域,然后实时监控热点的发生。热点发生后,会推送到集群中N台机器的数量,比如10台机器左右。在热点的情况下,我们可以用集群中的10台机器来承载它,而不是像以前那样一台机器。这里的核心关键是如何快速准确地发现并推送到其他数据节点。这个时候我们可能会在失效时间内读到脏数据,这对于大部分业务来说基本是可以接受的。如果不能接受,我们将不会启用此功能。技术挑战——性能与成本2017年出现了一个新的问题,就是随着Tair在阿里内部规模越来越大,有降本的要求,比如降10%、20%,甚至更多。成本优化最直接的任务就是提升单机单节点的服务能力。下图左边,大家可以看到,我们任何一个服务进程,基本上都会有锁。因为锁的存在,整个进程的性能不可能跑的很高,所以我们改造了整个MDB,包括今天的Tair。改造后尽量在单线程中完成每一个操作,相当于把锁尽量去掉,然后使用DPDK加用户态协议栈技术。经过一系列的优化,下图可以看到锁只占了1%。在32c的机器上,极限可以跑到500万的QPS,如果是64c的,可以达到几千万。这个吞吐量基本上是线性的。当然,真正在线上运行的时候,并不是跑到这么高的负载,而是要保证在高吞吐量、低延迟和稳定性之间的权衡。这项工作的成果之一——TairHotRing,我们也在FAST大会上发布了。以上是近年来Tair在阿里集团内部面临的一些重要的技术挑战,比如稳定性、单元化、性能成本等。3.云原生内存数据库Tair产品形态经过多年的演进,阿里云的内存数据库Tair已经全面兼容Memcache&Redis,部分兼容我们的图引擎,兼容开源的Gremlin和Neo4j的Cypher。我们还有一个支持标准SQL的引擎,我们用它来进行高性能的实时数据处理。所以我们今天对Tair内存数据库的定义就是缓存,加上高性能数据库和实时数据处理的定义。Tair产品的架构形式其实和我们今天在阿里云卖的Redis是一样的。分为标准主从版、双副本主从版、集群版。那么最大可以从1G扩展到几个T,那么它和社区托管的Redis有什么区别呢?基于持久内存和云盘,我们推出了持久内存类型和容量存储类型。这两种类型实际上可以满足客户对访问量和容量有不同要求的情况和场景。性能提升,它的整体性能会比开源的Redis提升两倍甚至更多,包括我们在里面做了很多企业级的功能,面向客户的关键业务场景。我们今天主要推广两种形式。一是Tair性能提升。这相当于客户业务的核心关键场景。我们建议客户选择它。与开源的Redis相比,首先性能更强,可以支撑运营活动或业务变更带来的流量激增,访问连接数会更多。事实上,开源的Redis很难支持上万个活跃连接,而Tair的性能提升实际上可以支持上万个。比如我们其实看到很多客户使用社区版的Redis,采用的是一主五从的读写分离。从这个架构我们可以看出整体的可扩展性很低。它是从slave节点读取的,但是读取的一致性其实是比较弱的。因此,我们向客户推荐Tair的集群版本。最终价格比社区版贵1.2倍,但整体容量是社区版的4倍,包括总吞吐量。也是4倍。因此,Tair的性能增强版在很多场景下相对于开源版本对客户的整体TCO更有优势。2018年之后,我们在持久化记忆的形式上花费了很多经验。有两个核心目标。首先是提供一个比社区Redis成本更低的系统,性能和Redis差不多。吞吐量是redis社区版的90%+左右,成本是社区版的70%左右。优于社区版的是每一个操作都可以持久化,落在持久内存上。下一页是我们的持久内存性能比较。左边是Redis6.0,右边是Tair持久内存版本。我们可以看到写和读性能的总吞吐量在90%+左右。在右图中,客户端延迟为P95(us)。我们去除了Redis中的AOF重写机制,因此毛刺抖动更低。读取确实比全内存版本慢,因为持久内存本身的访问延迟会高一点。接下来我们看第4部分,这部分其实是讲支撑我们Tair产品形态的关键能力,包括跟开源的Redis的核心区别和关键技术点?我们先来看看客户使用Redis的一些痛点。4.云原生内存数据库Tair的关键能力4.1Redis的一些痛点我们来看看左右两个痛点。为什么会这样?其实总结一下就是开源Redis在大量访问链接下性能会下降。但是在容器化时代,应用服务器越来越多,每个应用的访问连接数也会越来越多,几万个是很常见的。另外,在延迟&抖动方面,Redis其实是单线程的。在这种情况下,只要它有一个慢查询,比如Hgetall,往往会拖慢整体。其他短查询也没有处理好。HA高可用会造成误判。和之前一样,当一个Hgetall比较大的时候,处理线程会占用CPU,HA判断活动可能处理不完,所以它的整个数据操作和控制操作都在一个worker线程内处理。也没有区分整体内存统计,所以用户经常会发现配置了实例内存,还没有用完就发生了数据淘汰。那么,我们从内核技术的角度来说说Redis和Tair的一个区别。4.2RedisvsTair上图左边是6.0之前开源的Redis,是单线程的。6.0以后,号称是多线程的,但是从右图也可以看出,它只是在IO处理上是多线程的,但是在内部真正的数据操作上还是单线程的。做。为什么让它成为多线程如此困难?一是因为在原来的Redis中,一切都是单线程的,大部分操作都没有加锁,所以改成多线程非常困难;第二,代码是10年前写的,没有返工过。但是历史代码的优化难度相对较大。对于Tair,我们脱离了Redis,从头开发。我们将网络接收线程和工作处理线程分开,可以灵活配置为N×M;这样一来,Tair就可以处理几十万活跃的连接数,因为有足够的网络线程,单机的处理引擎可以提升得足够高,甚至可以跑到百万级别。业内也有讨论,做分布式好还是单机好?在我看来,在很多情况下,单机形式会有很多优势。如今,业务变得越来越复杂。如果是分布式的话,经常会出现一些跨节点的计算,甚至这些计算都需要有交易。形成集群后,跨节点的计算和交易会变得越来越复杂和难以处理。在这种情况下,为客户提供大规格、大访问处理能力的单机引擎其实是最合适的。当然我们也在多线程内部做了一些慢查询请求,实时监控,分离到慢查询请求池中。对于这类工作,我们尽量保证用户的请求能够在相对一定的访问时延内返回给用户。接下来我们看一下Tair引擎的高可用。前面我们谈到了Redis的社区版本。它的探索和数据操作实际上是在一个工作线程中。因为数据操作比较慢,会出现一些误判,所以我们把所有的控制请求放到一个独立的处理系统中;完全隔离这些访问和统计信息,包括用户数据访问和系统高可用性统计,以确保更好的质量。接下来说说Tair的集群架构。4.3Tair的集群架构Tair的集群架构,包括重定位缩放,与开源社区版完全不同。开源社区都使用Gossip,相当于P2P进行信息同步和探索。另外,当它的节点越来越多的时候,它在集群中实现信息一致性的速度会越来越慢。社区版的迁移和扩容都是基于key级别的,所以当key很大的时候,往往会出现一些迁移卡顿等情况,这时候会出现一些HA误判。我们现在在这方面做了一些改进,相当于中心节点对整个集群进行HA判断,包括集群管理。整个数据迁移都是按slot进行的,所以整个迁移速度会比key快很多。4.4具体重要场景的优化Pubsub相当于Tair和Redis进行消息处理。原来的单线程,如果挂载的客户端很多,其实推送会比较慢。它的单线处理相当于在Tair中把它当作多线程处理,所以这是一个并发处理操作。4.5TairStack:丰富的数据模型TairStack拥有丰富的数据模型,其实是阿里内部实践中积累的通用数据结构,目的是让业务开发更简单。从上图可以看出,我们开源的一些包括:TairHash、TairString等,这些结构也可以用在开源的Redis中,并且完全兼容开源的Redis。这些模块也可在公共云上使用。被很多客户使用。接下来,让我们看看Tair的企业级能力。4.6Tair的企业级能力Tair的企业级能力这里主要讲三个部分,包括全局多活、安全能力、Tair引擎可观察性。全球多货现在的一些客户,尤其是中大型客户,希望在多个区域做多货。那么今天我们就可以实现三个区域多个活动的同步。它的原理是利用Binlog在3个地方做多个activity。我们还建议,当应用在做多个任务时,可以在应用层面通过key分发到多个单元,这样更容易避免冲突。安全能力安全能力部分在公有云上也是一个重要的地方。我们提供给客户的实例在VPC内部,整个网络的安全得到保障。客户可以通过SSL加密访问方式访问Tair,可以进行更高级别的访问通信加密。我们有一个功能叫PITR,可以帮助客户将数据恢复到客户指定的任意时间点,下到秒级。另一个重要功能是用户审计。经常有客户说,我的流量怎么这么大?这个访问源是从哪里来的?或者我的数据被清理了,通过这个可以看到删到哪里去了。所以在整体的技术实现上,我们其实做了一些高频快照,你可以认为是全量快照,加上增量Binlog,帮助客户恢复到那个时间点。Tair引擎的可观察性在可观察性上也投入了很多。当然,还有一些事情没有做得特别好。比如集群级别的聚合工作其实已经探索过了。我们可以实时看到有热键和访问量比较大的键,包括在引擎层面,可以看到每个操作的访问延迟。一旦慢了,我们就可以看出是哪一部分操作慢了。5、Tair在电子商务中的应用:Tair在电子商务中主要用于缓存和内存存储,一般用于登录系统、用户系统、商品系统、购物车、个性化推荐等。游戏方面:除了低延迟、弹性扩展、高可用之外,游戏客户最看重的是备份回滚、无感扩容。在我们今天的积极扩张下,它的业务不会下降。这是通过我们的整体集群解决方案提供给客户的,包括数据迁移解决方案。金融和安全风控:在金融和安全风控方面,Tair做了一些计算,比如某段时间内购买的商品数量,这种计算可以用来防止黄牛作弊。生活服务:LBS生活服务主要通过实时功能完成。它和RedisGeohash最核心的区别在于Geohash只能做点对点的邻近查询,比如它只能搜索离我最近的10km的人或者最近的商店。6.总结第一部分讲Tair从阿里巴巴集团到阿里云历时13年的发展,并推向客户。从单个缓存开发,帮助客户构建多样化的实时场景。第二部分是阿里集团在过去几年面临的一些重要的技术挑战,包括热点、多活、性能、成本等问题的解决和优化。第三、四部分是通过Tair自研引擎,充分利用云基础设施上的不同存储介质,为客户提供更合适的选择和更高的服务SLA。最后,Tair的应用解读帮助客户搭建在线实时场景。
