数据结构论坛

首页 » 分类 » 分类 » 阿里云原生内存数据库Tair在游戏场景的
TUhjnbcbe - 2021/8/20 12:55:00
北京手足癣专科医院 http://baidianfeng.39.net/a_cjzz/210119/8604561.html

内容简要:

一、游戏系统中的Redis

二、云原生内存数据库Tair介绍

三、Tair的游戏场景

一、游戏系统中的Redis

(一)RedisInGamingServers:分区分服

游戏的架构非常多,总结来看基本有三种,第一种是分区分服的游戏,第二种是全区全服,第三种是全球同服。最近全同服的游戏比较火,线上做了很多收割,而分区分服也适用于一些游戏场景。

Redis的使用场景可以分为两种,一种场景是当缓存使用,另一种场景是当内存数据库使用。Redis的使用场景在国内外的定位是不一样的,在国外大多数Redis都是作为缓存使用,但在国内,可以说70%的用户是当做内存数据库。

下面就用一个分区分服的场景来介绍下Redis的典型用法。

在游戏登录的时候,这些关系型数据,包括用户数据、用户账单、计费记录等肯定是在关系型数据库里。这里Redis的特点是,比如有一个注册活动或者新服开放,当大量的用户进来后,我们就需要使用一些缓存来抗住压力,

所以这里的Redis的使用主要是缓存场景。

第二块是分区分服里最核心的GameServer。

GameServer是一个强内存的计算型服务,它不会有核心的服务在数据库里面,但它的一些周边服务,比如排行榜,还有一些通用的服务,比如分布式锁,对战匹配,选角记录等都通常放到Redis里边。

还有一块是图中间的部分。当GameServer变更到一些数据,如游戏用户的经验变化,游戏获得的装备,这些核心关键数据也是存入关系型数据库,因为这些东西都是游戏资产,上方红色部分的场景在RDS里是做缓存。

除此之外还有一些周边系统,在这种分区分服游戏里,一般也有一些跨服对战。消息队列,mailbox等。这些数据也经常放在Redis中,使用方便,性能也很好。

还有最后一块是上图右下角的部分,游戏公司经常会做一些活动,比如做一些宣传,还有类似于防作弊、防木马的情况,需要把用户日志落盘,这个每天生成的数据量很大,一般都会放到一个DataWarehouse或者一个分析型数据库如ADB里面供后续挖掘。此时游戏公司还需要分析活动是否成功,是否需要做投放,Redis在这里提供工单缓存/分析加速。

以上是Redis在分区分服游戏中的一些使用场景。

(二)RedisInGamingServers:全球同服

另一个是最近热门的全球同服场景,上图是它最基本的技术架构。

全球同服的特点是,所有的国内外节点都是访问了同一份数据库。游戏行业的一个特点是对数据库的性能要求并不高,但是对网络和计算的要求非常高。在游戏行业里,我们常说最远的距离可能不是数据到数据库的距离,而是“电信到联通”的距离。在这种全球同服游戏架构里,有一个很复杂的问题就是数据既然集中了存储在一个地方,那么在长距离访问时就会遇到严重的体验问题。实际上,在这种全球同服的游戏架构里,它都会有一个CacheSvr,把远端的数据都缓存在本地,然后让本地的访问去增删查改它,降低访问时延,这是全球同服游戏架构里的一个核心技术。在cacheserver技术中,由于Redis本身可以作为很好的缓存,所以这里使用得比较多一点。

由于数据是集中式存储,当所有游戏用户都去访问一个大数据库的时候,要求还是很高的。对于Redis而言,一般都有一个RedisCluster可以提供访问。

以上是Redis在全球同服游戏里的使用场景。

(三)游戏对Redis的要求

如果游戏要用做高速存储、内存数据库等,那么它对Redis有哪些要求?

首先,对数据库的要求是可靠性。对于Redis来说,在电商场景和游戏场景中可靠性要求都很高,但是在例如链路管理上还是差别较大。例如,对于电商体系而言,链路管理的特点是出问题就断,宁可返回一个错误的结果,也不会Block,因为所有的电商链路都是NoBlocking,出现问题断了就好,下次再处理。但是游戏行业不一样,它需要很好的链路保持能力,可以慢慢解决,但是链接不能断,因为断了之后后端的业务就断掉了,业务层还挂着各种游戏的资源信息等,这是游戏行业跟电商行业不一样的一个地方。

一般情况下,很多游戏数据库平均的访问量都不大,但是不能出问题,第一是链路不能断,第二是如果扛不住的时候,要求能够平滑扩缩容。它对平滑性的要求特别高,因为当一个游戏突然火了,或者刚开服时有很多用户去注册登录的时候形成注册风暴,会发生大量扩容的行为,如果在扩容速度或者平滑性上有所欠缺,那么用户体验就特别差。

另外,在做一个全球同服游戏的时候需要考虑容灾和多活的能力。高可靠性对数据库类似于保险,抗热点、抗压力是保险,平滑扩容也是保险。

游戏对数据库有高可运维的要求。电商数据库基本不会涉及太多的运维,因为每天的工单,包括交易,购物,交易快照等都是存下来的,最多索引一下,不会来回搬数据。但是对游戏而言,由于每天产生的数据和日志特别多,并且游戏运营迭代特别快,比如有些分区分服的游戏,尤其做滚服、合服,迅速开一个新的服务器,把数据库导过去,然后去滚动,这些游戏运营模式对数据运维要求特别高。当游戏用户反馈说在游戏中丢了东西,我们需要帮他进行查找,因此需要支持数据恢复,还有内省、清洗等。

此外还有低成本。游戏行业有很明确的冷热效应,游戏刚开始特别火,等游戏热度慢慢降下来之后,需要迅速把数据存下来换出去,降低运营成本,这也是非常关键的一点。低成本考察的是介质,像Redis这种数据库,如果数据量都放到内存里,那么成本一定比较高。有一块节省成本的措施是极致弹性,比如今天游戏做活动,我们把数据给弹上去,明天再拆下来,只要有足够弹性,那么成本是可控的。

最后是快速开发。游戏行业的在开发上的特点是快速迭代,竞争比较激烈,推出游戏的速度特别快,如果成功,则马上准备下一版,不成功就很快收掉做下一个游戏。所以如果有框架支持,更多的API,提供更多的封装和语法糖,那么它可以很迅速地搭建适合自己的游戏体系。

二、云原生内存数据库Tair介绍

云原生内存数据库Tair(Redis企业版)是阿里云推出的支持高并发低延迟访问的云原生内存数据库,完全兼容Redis数据结构和API。支持主从与集群架构,采用多样存储介质应对不同数据温度场景,并提供全球多活、数据闪回和丰富的数据模型等特性,致力于帮助客户构建在线实时场景。

Tair兼容了Redis的数据结构,那么面向游戏行业,和Redis的差别主要是什么呢?

首先是容灾方面,开源的自建Redis没有很可靠容灾,但阿里云Tair通过可靠的高精度容灾模块,能够做到快速容灾,比如10秒级就可以切换掉一个有问题的数据库。

第二个是链接保持能力,游戏领域对链接保持的需求很高,这和电商、直播等领域不太一样。Tair通过代理层的热升级能力,将链接尽可能保持,确保了升级、宕机等多种情况下的可用性。

第三,一般数据库做容灾就是主备容灾,用Redis的时候也可以搭个主备出来,阿里云Tair除了采用多可用区容灾或跨可用区容灾之外,还提供了跨域多活容灾的能力。注意的是跨域容灾不一定是多活,但多活一定是跨域容灾。

还有就是备份,备份很关键,可以防止删库跑路等情况。游戏行业的特点是发版本的速度特别快,如果版本发错则需要快速回滚。Tair提供任意时间点的数据恢复,当游戏厂商发现发布的版本有问题,可以马上回滚,降低影响。除此之外,Tair还支持秒级数据闪回这样更精密的数据回滚能力,可以指定过去任意秒级时间点按key/keypattern或者全量恢复数据。

在这种日常运维中,可观测性是需要建设的重点,业务在运行中不可避免会遇到实时热Key、大Key。由于游戏迭代速度很快,质量方面难免偶尔出现问题,我们能够通过实时和历史Key分析快速找到这些瓶颈并解决问题。在Tair中除去能够迅速观测到热点,还能够迅速把热点加速掉,我们称之为散列技术,可以把热点的抗压能力轻松提升到10~30倍。

成本上,从我们的角度来看Redis,往内存里边放的东西越多,成本就越高,内存是所有的存储里最贵的。但是阿里云Tair有更好方式,我们有Tair持久内存型,很好地解决了存储成本和访问性能的矛盾。最早做持久内存的时候,它没有什么企业级特性,后续我们把企业级能力都搬到持久内存上,如今大家去买持久内存的话,就具备这些企业级能力,包括PITR、多活、加速等。

开源Redis的好处在于它跟一般的Key-Value不一样,它存很多结构化数据,跟数据结构更贴合一点,用得比较快一点。但是我们发现用户真正用起来的时候,这些结果是不够的。游戏用户大量使用JSON,比如存用户属性、道具等,都是JSON结构。所以Tair引擎里已内置了JSON结构,那么用户用起来就非常方便了。

三、Tair游戏场景介绍

(一)Tair全球多活

Tair有一个典型的场景是全球多活。

这个是线上的一个例子,例如游戏里中国用户可以到美国的商店里去买一个光环装备,然后这个用户在国内服务器上就具有了一个光环。

全球多活是基于引擎高可靠的数据多活服务,Tair提供全球同服的高效CacheServer,数据库本身具备多活,数据写入一个地方,那么所有地方都可见。

多活在游戏里基本是用在CacheServer上,所有互联网类的用户都会有一个登录Session系统,如果要去把Session系统做大,做一个很可靠的全球多活Session,Tair也能支持。

(二)数据闪回-任意时间点数据恢复

Tair另外一个经典场景是任意时间点的数据恢复,它实际上是数据安全的一部分。数据安全包括链路加密,也包括存储加密,还包括多副本等。

但任意时间点数据恢复这个场景游戏客户用得最多,大约占90%。游戏厂商在发版本的时候,如果出现问题可以快速回滚,也支持只回滚某一些东西。回滚既支持把数据恢复到源,也支持克隆一个新实例来恢复。

(三)CAS/CAD高性能分布式锁

刚才我们从分区分服的服务器里边也看到了,Redis本身会作为GameServer的一些周边服务,最简单一个例子就是分布式锁。多个机器同时去拿一个资源的时候,牵扯到资源竞争肯定要有锁,业务需要通过分布式锁来解决。但这个分布式锁很少有人实现的对,所以我们就直接把分布式锁做在这个引擎里面了。

分布式锁比起一般的锁,它除了有互斥性,还有租约性。一般会在锁上加一个Timer,设置锁多长时间,当租约到期后,锁自动释放。

分布式锁存在的问题不是加锁的地方,而是释放的地方。举个例子,比如一个应用程序去加了锁,应用程序没有挂,但是时间拖得长一点,然后等到引擎里面的Timer超时,锁就释放了。结果第二个应用程序就拿到锁了。当这个APP又跑起来的时候,我们一删锁就把别人的锁给删掉了,会引发资源错误。

因此,难点在删除这一步,删除时的要求是只能删自己的锁,不能删别人的锁。所以很多的云上用户,如果用去del命令去删Key的话就删错了,正确的实现是一个事务操作,而Tair直接在引擎里实现了分布式锁。

阿里内部90%的分布式锁都是使用Tair的高性能分布式锁,包括许多游戏客户也经常使用。

(四)TairDoc:游戏业务快速迭代

另一个核心的module能力就是TairDoc,因为JSON数据结构是游戏用户里最大的特征结构,我们更新JSON的时候不需要该表,直接在对应的JSON数据中增加相应信息即可。

(五)TairZset:多维/多条件实时排序

排行榜是游戏场景的最常见应用,也是Redis的一个主要应用场景,甚至有些大型游戏公司有一个专门的排行榜组,给全平台游戏人员提供排行榜服务,而非直接暴露一个Rediszset接口。在具体开发实现中,会遇到如下两个主要的问题。

第一个问题是在对战的时候,玩家选择排行榜上的其他玩家PK,肯定也是选一个分数和时间差不多的,因此,做排行榜的时候是多维度的。例如在直播网站,可以看到在线人数,粉丝点赞数,礼物金额等。如果按照一个个维度去做的时候,那么很难做一个很精确的使用。开源的Redis只能提供一维的排行榜,而Tair则可以提供包含多个Score的多维排行榜,这样的多维/多条件实时排序能力很好地解决了这个问题,开发者使用起来也会非常的敏捷顺手。

第二个问题是当游戏特别大的时候,例如游戏用户有万人,那么万人的排行榜是非常大的了,在这样规模排行榜程序设计上把所有的用户都存在一个Key下面,Redis就会发生数据倾斜,性能也不是特别好,而如果要把Key拆开,因为排行榜既不符合分配率,也不符合交换率,所以拆的话也比较难。针对这个痛点,通过TairJedis更可以创建分布式排行榜,非常敏捷的构建大规模、高灵活度的排行榜应用,用户可以根据业务容忍度和性能诉求选择分布式精确/非精确排行榜而不用

1
查看完整版本: 阿里云原生内存数据库Tair在游戏场景的