默认
打赏 发表评论 3
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
微信后台基于时间序的海量数据冷热分级架构设计实践
阅读(115417) | 评论(3 收藏5 淘帖2
微信扫一扫关注!

本文将为你介绍,微信后台的一种基于时间序的海量数据冷热分级架构。应对 PB 级数据、每天万亿级访问、键值带来的挑战,微信技术团队是这样做的。


1、作者介绍


微信后台基于时间序的海量数据冷热分级架构设计实践_author.png 杨平安:
- 12 年加入腾讯,在微信技术架构部的基础平台组负责存储系统的开发。
- 先后参与了 QuorumKV\PaxosStore 等项目,伴随微信存储成长。
- 一路起来,见证了微信存储架构的演变。

2、写在前面


2020年4月6日最新动态:时隔3年,微信团队再次分享了本文所述架构的最新升级版本及其改造过程,有兴趣可以前往阅读《微信后台基于时间序的新一代海量数据存储架构的设计实践》。

微信的后台数据存储随着微信产品特性的演进,经历了数次的架构改造,才形成如今成熟的大规模分布式存储系统,有条不紊的管理着由数千台异构机型组成的机器集群,得以支撑每天千万亿级的访问、键值以及 PB 级的数据。

作为以手机为平台的移动社交应用,微信内大部分业务生成的数据是有共性可言的:数据键值带有时间戳信息,并且单用户数据随着时间在不断的生成。我们将这类数据称为基于时间序的数据。比如朋友圈中的发表,或者移动支付的账单流水等业务生成的数据都满足这样的特征。基于时间序的数据都天然带有冷热分明属性――这是由手机的物理特性决定的,它的尺寸有限的屏幕所展示的数据只能分屏,通过手指的滑动,平滑而又连续的沿时间轴依次访问――通常是由最新生成的数据,慢慢回溯到较早前的数据。同时朋友圈等业务都是信息读扩散的应用场景,这就意味着它们生成的后台数据具有读多写少的鲜明特征。

在微信的实际应用场景中,这类数据的主要特点包括:数据量大、访问量大、重要程度高等。

以上特点在现网的实际运营过程中,给我们带来了非常大的挑战,主要包括:

  • 数据量大:需求的存储容量高――基于时间序的数据通常不会删除,而是随着时间不断积累,数据量达到 PB 级别,相应需要的存储空间也与日俱增;
  • 访问量大:节日效应明显――基于时间序的数据往往是热点业务生成的数据,它们的访问量居高不下,基本维持在每分钟数十亿次的级别。尤其是在节日期间,瞬发访问量更可达平日的三至五倍;
  • 重要性高:用户感知明显,数据一旦丢失,导致用户不能正常使用产品,并因此而转化成的投诉率高。

通过堆机器来横向扩展存储自然可以应对如上的各种挑战,然而在成本预算紧张的前提下,机器数目是有限的。在这种情况下,基于时间序的海量数据的冷热分级架构便应运而生。该架构正是为了应对后台日益膨胀的这类数据,本着充分利用机器资源,发挥各种硬件介质特长的原则,结合数据的冷热分明、读多写少的访问特征而开发和设计出来的。它基于数据分层的理念,根据不同时间段的数据在访问热度和数据量上的差异,定制不同的服务策略,在纵向上扩展存储的边界。横向扩展存储是易于理解的,通过向原集群中增加相同类型的机器――其中必然涉及到一轮历史数据的迁移――最终新旧机器负载均衡,彼此之间并无差异的对外提供服务。在这种方案下,数据横向流动,系统一视同仁的对待,显然并无因地制宜思想的容身之所。

而纵向扩展存储的架构便提供了这样一种思路:

  • 对热点数据:数据量少,但承担的访问流量大,我们当然是希望它们能常驻内存,因此系统提供了有强一致保证的内存层,在应对突发流量时,也可在不涉及历史数据迁移的前提下,单独、动态的快速扩展内存层;
  • 对历史数据:数据存量大,但承担的访问量非常有限,我们当然是不希望用昂贵的固态硬盘来存储它们,因此,系统提供了廉价的机械盘层,并且有一套透明的冷数据剥离和批量下沉的流程,将存储层中历史数据源源不断的抽离到机械盘层。

通过这样的一种纵向分层、单独扩展的思路,即为我们系统提供了极大的灵活性,解决了节日期间存储层面临的内存瓶颈,以从长远的角度为我们缓解了成本压力,解决了存储层面临的磁盘容量瓶颈。

当然一套成功的大型分布式系统仅有这些是不够的,还必须包括数据多副本复制策略以及分区算法等,也要有能应对复杂的现网运营环境的能力。我们结合各层的服务特点,制订了相对应的数据强一致算法,如内存层通过版本号控制来保证与存储层的完全一致,存储层通过 Paxos Group 实现多副本容灾,而机械盘层则通过串行写来保证。我们同时也实现了自己的去中心化的数据路由算法,确保了数据和流量的均匀分布,并且保证这种特性在横向扩展后依然成立。

通过如上工作的努力,环环相扣,我们的基于时间序的海量数据的冷热分层架构成功的应对了 PB 级数据、千亿级访问以及万亿级键值带来的挑战。

3、系统设计


1数据模型


本文提及的海量数据的冷热分级架构是专门服务于基于时间序的数据,它们主要特征为:

  • a). 数据键值带有时间戳信息 ;
  • b). 单用户数据随着时间在不断的生成。

我们设计的架构强依赖于特性 a),各个环节基本上是依赖于键值中的时间戳来分发数据或者进行数据排序的。至于键值中的时间戳如何生成、全局是否维持统一时间、如何维持等则不在本文的讨论范围,通常这由前端的业务特性以及后台的时间服务器策略决定的。

而特性 b) 则保证了本架构的必要性、实用性。如果数据规模有限,以用户的账户信息举例,它就像我们日常生活中的户口本,它只有一份,对单用户而言不会新增。则我们通常用固定的机器集群存储就可以,并且鲜有变更。而我们要处理的是用户的日记本、或者记账簿,它们每天都在不断生成新数据。

我们以现网某个集群的实例情况举例,说明下此类业务数据有如下的特点:

  • 1. 数据量大:PB 级数据,万亿级键值,并且在源源不断的生成中,然而新生成的数据相较于历史存量数据占比小。下图展示了该集群数据在各时间段的一个占比情况;
    微信后台基于时间序的海量数据冷热分级架构设计实践_1.jpeg
  • 2. 访问量大:峰值可达每分钟数十亿次访问,尤其是在节日期间,用户高涨的热情更可以转化成平日三至五倍的访问量。同时具有冷热分明、读多写少 (读写比例甚至可达 100:1) 的访问特征,比如节日期间倍增的访问通常是对节日期间生成的新增数据的访问。下图展示了该集群访问在各时间段的一个占比情况;
    微信后台基于时间序的海量数据冷热分级架构设计实践_2.jpeg
  • 3. 数据安全性要求高:这类数据通常是用户感知敏感数据,一旦丢失,转化成的用户投诉率高。

2系统架构


系统由三个层次组成,如图所求,分别是内存层、存储层(热数据存储层)以及机械磁盘层(冷数据存储层)。

从时间轴上看,它们服务的数据由热至冷,如下图所示:
微信后台基于时间序的海量数据冷热分级架构设计实践_3.jpeg

从客户端的角度看,三层都是并列的,客户端都会直接的与某层中的某台机器发生通信。具体的区别点在于,内存层和机械磁盘层对客户端而言是只读的。所有的写都是由客户端直接写向存储层。我们将去中心化的配置分发到客户端机器上,配置的类型包括内存层路由、存储层路由以及其它元数据,客户端根据配置中的时间分隔点以及流量比例,来决定将当前的读请求分发到内存层还是存储层的具体机器上。配置支持快速分发和动态加载,可以在秒级实现更新。

机械磁盘层的路由对客户端而言是透明的,存储层保存了下沉到机械磁盘层的数据链接,链接包含了文件编号、内部偏移和大小,而客户端对此是不知情的。当已下沉数据的读请求分发到存储层机器上时,存储层会计算出该数据各副本在冷数据存储层对应的机器地址,然后将它和文件链接一起回复给客户端。客户端再按照随机的策略在多副本之间选择一份读取,从这个角度看,冷数据存储层对客户端而言更像个远程文件系统,而 inode 信息和路由表是放在热数据存储层的。

下面我们再详细的分析各层的设计策略。

3内存层


内存层从表现上更像是一个缓存代理,然而普通的缓存在处理数据有效性上是乏力的。常见的策略如写时淘汰,每次写存储层之前,都先清理掉缓存中相应的数据,确保失效。然而数据在缓存中通常也是多副本的,这个方案即无法处理网络分区错误,并且写时淘汰也会产生多次 RPC 请求,过份的消耗系统资源。另外一种常见策略是有限的数据一致性,即过时淘汰的策略。在将数据写入缓存时,会附带一个有效时间,在这个有效期内,该数据一直被认为是正确的,并不关心真实情况是如何的。这种缓存只能应用于对数据实时性要求不高的服务。对微信的敏感业务而言,我们更需要能保证数据强一致的分布式缓存。

我们通过版本号来实现了这一目的。我们为缓存中的每一份数据都维持了一份版本号,存储层中相应的也有一份。只有当缓存中的版本号与存储层的版本号达到一致时,才会认为缓存中的数据是有效的。所以,客户端每次对内存层的读请求,都会由缓存层相应的产生一次读请求发到存储层。在一次 RPC 请求中完成有效性的识别以及过期数据的更新。

微信后台基于时间序的海量数据冷热分级架构设计实践_4.png

从直觉上看,采用这种方案的强一致缓存并没有降低存储层的访问压力。因为客户端对缓存层的请求,与缓存层对存储层的请求是 1:1 的。然而这个方案点的关键在于,我们成功的疏解了存储层的内存瓶颈。将存储层缓存数据的功能,转移到缓存层的内存上。我们现在对存储层的要求就是能够尽量的缓存更多的版本号,提供高效的版本号访问能力就可以了。从这种意义上来看,这个强一致性缓存就是存储层内存的延伸。因此,我们将它称为内存层。它的优势在于可动态的调整流量比例,并且可以在访问高峰期快速的扩容。后面的章节我们也描述了如何通过工程手段优化版本号交互带来的资源消耗。

为了系统的健壮性,一些异常情况也是需要考虑的,如果一台内存层机器突然离线,会有数十 G 的缓存数据失效,我们当然不会希望这数十 G 数据的压力,会全部的落到一台存储机器的磁盘上。――这无疑会引起系统的抖动。因此,我们按照组的方式来部署了内存层。每组有多台机器。一份数据可能在这多台机器内有多个副本。客户端通过随机的次序访问这些机器。这样就尽力避免了单结点失效对整个系统的影响。

我们在内存层中设计了简单、轻量的支持变长数据的缓存结构。每台机器包含数十条 LRU 链,每条链都是一个共享内存形式的一维数组。所有的数据都追加写在数组的最新位置,到尾部后就从头开始循环。自然,这样的结构需要一个索引来记录数据的位置。这种方式固然浪费一些内存空间,但避免了内存的动态分配。

4存储层


存储层在整个系统架构中处于核心的位置。内存层和机器硬盘层都依赖于它的实现。前文提及,提供高效轻量的版本号访问能力是强一致内存层实现的关键。同时,源源不断的将冷数据下沉到机械硬盘层的需求,就暗示了在存储层必须有这样一种特性:冷数据是易于从所有数据中剥离,并且收集的。――这样就意味着,如果在存储层中数据是平坦的,冷热数据混杂在一起,那么我们在抽离冷数据的时候,就要把硬盘中所有的数据遍历一轮,无疑会消耗比较多的系统资源。

因此我们采用了 lsm-tree 算法来实现这一需求。该算法和 B+ 树一样是种建立索引的技术。不同的是它基于多组件 (C0\C1 等组件),通过延迟提交和归并排序的方式,将 B+ 树的随机 IO 转变成了内存操作和顺序 IO。在我们的访问模型下,所有的写都是热点数据,只会提交到 C0 组件。然后在适当的时机,同 C1 组件中的数据进行多路归并排序。通过该算法,我们可以同时实现数据分层和数据有序的目的。

微信后台基于时间序的海量数据冷热分级架构设计实践_5.jpeg

Leveldb 是 Google 公司开源的存储引擎库,它正是基于 lsm-tree 算法的思想开发出来的。因此,我们复用了它成熟的数据结构组件,如日志格式、数据文件格式、内存表格式等。然而它其中的一些运行时策略,却会给我们的现网运营带来麻烦。比如说运行时不受限的 compact 策略、数据文件索引的懒加载等,会触发不可控的读盘,造成服务的抖动;同时大量的动态内存分配也会对机器的内存使用带来一定不可控的因素。因此,我们抛弃了这些运行时行为,定义了自己的管理策略,使系统变得更加可控。同时,我们利用不同数据的访问差异,对冷、热数据的存储进行了各自的定制,按照时间段定义按块压缩的粒度、索引的粒度等,行之有效的调和了 CPU、内存、磁盘容量、磁盘 IO 等系统资源之间的转换关系。

冷数据的链接和冷集群的路由表,都是记录在存储层中而对前端不可见的。具体的设计思想,我们在下节中详述。

5机械硬盘层


机械硬盘容量虽大,但是 IO 性能低下,故障率高。一种常见的思路是冷数据存储层独立与热数据存储层,而对客户端直接可见――客户端持有一份冷数据存储层的路由,并且独自路由――这无疑是种简单、易于理解的方案,但是在我们的应用场景中面临着两个问题:无法精确防空以及加剧机械硬盘层的 IO 紧张。

定义 TB 访问量为每 TB 数据的每秒的访问次数。在我们的应用场景中,每 TB 历史数据的实际访问量设为 N,则机械硬盘的服务能力仅为 N 的一半。如果冷数据存储层独立,则它需要自己维持所有的数据索引,而内存容量不足以支持数十 T 数据的索引,只能将索引落盘,则每次对数据的读取都要带来两次随机读盘。因此,我们将冷数据索引以及冷数据存储层的路由表,都放到了热数据存储层中,而对前端不可见。

为了容灾,我们必须为每份数据存储多份副本。如果采用双副本方案,则系统需要冗余 50% 的访问能力,以应对另外一份副本失效的情况,在 io 瓶颈的前提下,这种方案是不可取的。因此我们采用了三副本方案,只要冗余三分之一的能力。每份副本分布在不同的园区,可以实现园区级的容灾。

微信后台基于时间序的海量数据冷热分级架构设计实践_6.jpeg

由于机械盘容量大、计算能力差,我们采用 NO RAID 的方式组织了盘组。为了更好的实现单盘失效导致数据丢失的故障的灾后恢复,我们实现了同组三台机器在盘级别数据的完全相同。为了达到盘级别的负载均衡,我们通过预计算路由、硬编码的方式,实现了 (数据 ->机器 ->盘 ->文件) 的单调映射,由数据的键值可以直接定位到盘的索引以及文件的编号。

微信后台基于时间序的海量数据冷热分级架构设计实践_7.jpeg

作为机械硬盘层的补充,一个冷数据下沉的模块是必须的,它作为冷数据存储层的唯一 Writer,我们通过两阶段提交的方式确保了下沉过程的透明性,通过控制流程发起时机保证资源使用不影响现网服务,通过预占位、串行写入的方式,确保了数据在冷数据存储层文件级别的完全一致。

4、数据强一致性保证


业务要求系统必须保证在数据的多份副本之间保持强一致性。――这是一个历久弥新的挑战。我们将分内存层、存储层、机械硬盘层分别来考虑数据的强一致性维持。

1强一致缓存


正如前文描述,内存层作为一种强一致性分布式缓存,它完全是向存储层对齐的,自身无法判别数据有效性,本身多副本之间也没有交互的必要。它对前端而言是只读的,所有的写请求并不通过它,它只能算是存储层中数据的一个视图。所以它对前端数据有效性的承诺完全是依赖于存储层的正确性的。

2Paxos Group


我们基于 Paxos Group 实现了存储层的数据一致性,通过采用无租约的方式,使得系统在保证强一致性的前提下达到了最大的可用性。Paxos 算法是由 Lesile Lamport 在论文中首提的,它唯一的作用是在多个参与者之间唯一的确定一个常量值。――这点同分布式存储没有直接关联的。我们在 Paxos 算法的基础上,设计出基于消息驱动的 Paxos Log 组件――每一条操作日志都要 Paxos 算法来确定,再进一步实现了基于 Paxos Log 的强一致性读写。

Paxos Group 因为采用了无主模型,组内所有机器在任一时刻都处于相同的地位。Paxos 算法本质是个多副本同步写算法,当且仅当系统中的多数派都接受相同值后,才会返回写成功。因此任意单一节点的失效,都不会出现系统的不可用。

强一致性写协议的主要问题来源于 Paxos 算法本身,因为要确保数据被系统内的多数派接受,需要进行多阶段的交互。我们采用如下的方法,解决了 paxos 算法写过程中出现的问题:基于 fast accept 协议优化了写算法,降低了写盘量以及协议消息发送、接收次数,最终实现了写耗时和失败的降低;基于随机避让、限制单次 Paxos 写触发 Prepare 的次数等方法,解决了 Paxos 中的活锁问题。

强一致性读协议本身和 Paxos 算法并没有太大的关系,只要确认多副本之间的多数派,即可获取到最新的数据。我们通过广播的方式获取到集群中多数机器(包含自身)的 paxos log 的状态,然后判断本机数据的有效性。

当系统中的单机节点失效,数据完全丢失的时候――这种情况是可以算是 Paxos 算法的盲区,因为该算法基于所有的参与者都不会违背自己曾经的承诺,即拜占庭失败而导致的数据不一致。――而这种情况在现网运营中可谓是常态,因此,我们引入了 Learner Only 模式。在该模式下故障机只接收已提交的数据,而不参与 Paxos 协议的写过程,意即不会因数据丢失而违背任何承诺。然后通过异步 catch up 和全量数据校验快速从其它副本中恢复数据。

为了防止多节点同时失效,我们将数据的多副本分布在不同园区的机器上。园区是同一个城市不同数据中心的概念。如此,我们的结构足以应对单数据中心完全隔离级别的灾难。

3串行写入


因为对客户端透明,冷数据下沉流程作为机械硬盘层的唯一写者,则该层的数据一致性是易于实现的。我们通过三副本串行写入、全部提交才算成功的方式来实现了多副本之间的数据一致性。

作为补充,冷数据集群为数据块增加了 CRC 校验和一致性恢复队列,当单机数据不可用 (丢失或者损坏) 时,首先客户端会跳转到其它备份中读 (三机同时对外提供读服务),一致性恢复队列会异步的从其它备份数据块中恢复本机数据。

因为采用了 No Raid 方式组织的盘组,并且同组机器间盘级别数据文件一致,在单盘故障引发数据丢失时,只要从其它机器相同序盘中传输数据文件即可。

5、数据分区


1静态映射表


数据分区的主要目的是为了确保同层机器间的负载均衡,并且当机器规模发生变化后,在最终仍然可以达到负载均衡的一种状态。

经典的一致性哈希算法的初衷是为了健壮分布式缓存,基于运行时动态的计算哈希值和虚拟节点来进行寻址。数据存储与分布式缓存的不同在于,存储必须保证数据映射的单调性,而缓存则无此要求,所以经典的一致性哈希通常会使用机器 IP 等作为参数来进行哈希,这样造成的结果一方面是数据的落点时而发生改变,一方面是负载通常不均衡。因此我们改造了此算法。

我们通过预计算虚拟节点随机数的方法,生成了割环点同实体机器之间的映射表。该映射表最多可支持一千组的集群规模,满足在任意组数情况下,实体机器间割段长度维持差异在 2% 以内;并且增加任意组数 (总组数上限不超过一千组),变动后的实体机器间的割段长度依然维持差异在 2% 以内。我们将此映射表硬编码,在运行时避免了计算的过程,数据根据键值哈希值寻址时,只要经过一次二分查找即可获取到对应的实体机器的编号。我们在内存层、存储层以及机械硬盘层都采用了这个映射表,保证了数据在各层路由算法的一致。在工程实现方面,我们可以合理使用这个特性来批量合并请求,以降低资源消耗,这在稍后的章节会有详细描述。

2组内均衡


组是数据分区的独立单元,是虚拟节点对应的实体单位。组之间是互相独立的。每组由多台物理机器组成,这是 Paxos Group 生效的基本单位。一份数据包括的多份副本分别散落在组内的各台机器上。为了在组内机器上保证负载均衡,我们同样设计了一套算法,规定了数据副本之间的访问优先级,前端会依优先级逐一的请求数据,只要成功获取,即中断这个过程。然后我们再将副本按优先级均匀的散落在组内机器上,如此即可实现组内负载的均衡。

3数据迁移


静态映射表是非常灵活的,在不达到组数上限的情况下,可以任意的增加一组或者多组机器。当然这个过程中一些数据的路由映射发生了改变,则就涉及到了历史数据的挪腾。为了在挪腾的过程中不影响服务,保证数据依然可读可写,我们开发出了对前端透明的,基于迁移标志位,通过数据双写和异步挪数据的方式实现的安全的、可回退的数据迁移流程。

4最小不变块


存储层和机械硬盘层通过冷数据链接耦合在了一起。因为两层使用了相同的映射表,那么当存储层因扩容而发生迁移时,那么冷数据链接无疑也要重新寻址,进行一轮重新定位。如果我们以单键值为粒度记录冷数据链接和进行冷数据下沉,那么在万亿键值的语境下,效率无疑是低下。因此我们设计了最小不变块的算法,通过两阶段哈希,使用中间的哈希桶聚集数据,将数据键值和冷数据存储层的机器路由隔离开来。通过该算法,我们可以实现:批量的转存冷数据、热数据存储层批量的以块 (block) 为单位记录冷数据链接、当热数据存储层发生扩容时,块 (block) 内的数据不因扩容被打散掉,而可以整体的迁移到新目标机上。

6、工程实现


糟糕的工程实现可以毁掉一个完美的系统设计,因此,如何在工程实现的过程中,通过技术的手段,提升系统的表现,同样值得重视。

1高效缓存


内存层的设计严重依赖存储层数据版本号的高效获取,那自然是版本号请求全落在内存中就可以了。因此,针对这种情况我们为定长的版本号设计了一套极简的、轻量的、行之有效的缓存――内存容量不足以支撑版本号全缓存。

微信后台基于时间序的海量数据冷热分级架构设计实践_8.png

它的数据结构只是一个二维数组,一维用来构建 hash 链,一维用来实现 LRU 链。每次读或者写都需要通过数组内数据的挪动,来进行更新。如此一来,我们就通过千万级数目的 LRU 链群,实现了缓存整体的 LRU 淘汰。它具有定长,可共享内存搭载,进程重启不丢失、内存使用率高等优点。

2批量操作


对系统服务器而言,前端访问过来的某个请求,其对应的逻辑操作都是串行的,我们自然可以梳理这个串行流程中的 CPU 消耗点进行优化。然而当主要的瓶颈被逐渐的消灭掉后,CPU 消耗点变得分散,优化效果就变得微乎其微了。因此,我们只能寻找其它突破点。

我们发现在存储引擎、一致性协议算法的实现流程中,逻辑操作步骤多,涉及到网络交互,硬盘读写等过程。因此,我们决定合并不同请求中的相同步骤,实现批量化操作,极大的优化了 CPU 消耗。

合并的代价即是耗时略有增加,我们通过快慢分离,只针对热点数据请求中的逻辑操作进行合并,去掉了耗时中的不稳定因子,减少了耗时抖动。

3请求合并


既然单机的逻辑操作性能已经得到了极大的提升,那么前后端的网络交互阶段,包括接入层的打包解包、协议处理等环节,成为了资源的主要消耗点。参考批量操作的经验,我们同样使用批量化的技术来优化性能――即将后台访问过来的单条请求 (Get) 在内存层聚合成一次批量请求 (Batch Get)。

4路由收敛


因为每个数据都是根据键值单独进行路由的,如果要进行请求合并,我们就必须确保同一个批量请求内的数据,都会寻址到相同的 Paxos Group 上。因此,我们必须在内存层将落到同一台存储机器上的 Get 请求聚合起来。我们首先在内存层和存储层采用了相同的路由算法,然后将内存层的组数同存储层的组数进行对齐,来完成了这一目标。

微信后台基于时间序的海量数据冷热分级架构设计实践_9.jpeg

7、相关工作


在设计的阶段,我们充分的调研了业界的各类方案,大到系统的整体架构,小到具体的技术点。各种方案自有应用场景、各有千秋,不能单纯以好坏区别,我们同样基于自己的业务场景,谨慎的选择合适的方案,或者弃而不用。在此尽量叙述。

处理 SNS 类业务生成的数据,业界有多种的冷热分离架构可以参考。我们以 Facebook 的 Cold Storage 系统举例而言,它也是基于冷热分层的想法,设计出了服务它们照片业务数据的存储方案。不同的是它采用了软硬件结合的方法,一方面定制专门的服务器(包括硬盘、电源等)和数据中心,一方面降低冷数据的备份数、增加纠删码等手段。

然而它们的经验我们是无法彻底套用的,主要两种原因:我们可使用的机器机型是固定的,不存在自己定制硬件的条件。同时它处理的是照片这种大 value 的数据。而我们基本上是文本这种类型的小 value 数据。从前文提及的 TB 访问量角度来看,它们处理的数据是容量瓶颈的,而我们处理的是 IO 瓶颈的,可以算是不太冷的冷数据带来的挑战。所以,我们只能实现自己的冷数据管理策略。

同样,业界有诸多关于如何实现数据一致性的方案。包括我们微信自研的 Quorum 协议,它是一种 NWR 协议,采用异步同步的方式实现数据多副本。即然是异步同步,那在多副本达到最终一致,必然存在一个时间差,那么在单机出现离线的情况下,就会有一定概率导致数据的不可用。而我们追求的是在单点故障下,所有的数据都保证强可用性。

因此,我们采用了无主的去中心化的 Paxos Group 实现了这一目标,其中非租约是 PaxosStore 架构的一个创新亮点。在故障时通常系统是抖动的,会有时断时续的状况,常见的租约做法在这种场景下容易出现反复切换主机而导致长期不可用,而 PaxosStore 的非租约结构能够轻松应对,始终提供良好的服务。PaxosStore 核心代码正在整理开源当中,预计四季度会正式发布,同时该项目的底层框架也基于我们已开源的协程库 github.com/libco。

(原文链接:点此进入

附录1:更多QQ、微信团队原创技术文章


微信朋友圈千亿访问量背后的技术挑战和实践总结
腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)
腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)
微信团队分享:微信移动端的全文检索多音字问题解决方案
腾讯技术分享:Android版手机QQ的缓存监控与优化实践
微信团队分享:iOS版微信的高性能通用key-value组件技术实践
微信团队分享:iOS版微信是如何防止特殊字符导致的炸群、APP崩溃的?
腾讯技术分享:Android手Q的线程死锁监控系统技术实践
微信团队原创分享:iOS版微信的内存监控系统技术实践
让互联网更快:新一代QUIC协议在腾讯的技术实践分享
iOS后台唤醒实战:微信收款到账语音提醒技术总结
腾讯技术分享:社交网络图片的带宽压缩技术演进之路
微信团队分享:视频图像的超分辨率技术原理和应用场景
微信团队分享:微信每日亿次实时音视频聊天背后的技术解密
QQ音乐团队分享:Android中的图片压缩技术详解(上篇)
QQ音乐团队分享:Android中的图片压缩技术详解(下篇)
腾讯团队分享:手机QQ中的人脸识别酷炫动画效果实现详解
腾讯团队分享 :一次手Q聊天界面中图片显示bug的追踪过程分享
微信团队分享:微信Android版小视频编码填过的那些坑
微信手机端的本地数据全文检索优化之路
企业微信客户端中组织架构数据的同步更新方案优化实战
微信团队披露:微信界面卡死超级bug“15。。。。”的来龙去脉
QQ 18年:解密8亿月活的QQ后台服务接口隔离技术
月活8.89亿的超级IM微信是如何进行Android端兼容测试的
以手机QQ为例探讨移动端IM中的“轻应用”
一篇文章get微信开源移动端数据库组件WCDB的一切!
微信客户端团队负责人技术访谈:如何着手客户端性能监控和优化
微信后台基于时间序的海量数据冷热分级架构设计实践
微信团队原创分享:Android版微信的臃肿之困与模块化实践之路
微信后台团队:微信后台异步消息队列的优化升级实践分享
微信团队原创分享:微信客户端SQLite数据库损坏修复实践
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(下篇)
腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(上篇)
微信Mars:微信内部正在使用的网络层封装库,即将开源
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
开源libco库:单机千万连接、支撑微信8亿用户的后台框架基石 [源码下载]
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
Android版微信从300KB到30MB的技术演进(PPT讲稿) [附件下载]
微信团队原创分享:Android版微信从300KB到30MB的技术演进
微信技术总监谈架构:微信之道——大道至简(演讲全文)
微信技术总监谈架构:微信之道——大道至简(PPT讲稿) [附件下载]
如何解读《微信技术总监谈架构:微信之道——大道至简》
微信海量用户背后的后台系统存储架构(视频+PPT) [附件下载]
微信异步化改造实践:8亿月活、单机千万连接背后的后台解决方案
微信朋友圈海量技术之道PPT [附件下载]
微信对网络影响的技术试验及分析(论文全文)
一份微信后台技术架构的总结性笔记
架构之道:3个程序员成就微信朋友圈日均10亿发布量[有视频]
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
快速裂变:见证微信强大后台架构从0到1的演进历程(二)
微信团队原创分享:Android内存泄漏监控和优化技巧总结
全面总结iOS版微信升级iOS9遇到的各种“坑”
微信团队原创资源混淆工具:让你的APK立减1M
微信团队原创Android资源混淆工具:AndResGuard [有源码]
Android版微信安装包“减肥”实战记录
iOS版微信安装包“减肥”实战记录
移动端IM实践:iOS版微信界面卡顿监测方案
微信“红包照片”背后的技术难题
移动端IM实践:iOS版微信小视频功能技术方案实录
移动端IM实践:Android版微信如何大幅提升交互性能(一)
移动端IM实践:Android版微信如何大幅提升交互性能(二)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
移动端IM实践:iOS版微信的多设备字体适配方案探讨
信鸽团队原创:一起走过 iOS10 上消息推送(APNS)的坑
腾讯信鸽技术分享:百亿级实时消息推送的实战经验
IPv6技术详解:基本概念、应用现状、技术实践(上篇)
IPv6技术详解:基本概念、应用现状、技术实践(下篇)
腾讯TEG团队原创:基于MySQL的分布式数据库TDSQL十年锻造经验分享
微信多媒体团队访谈:音视频开发的学习、微信的音视频技术和挑战等
了解iOS消息推送一文就够:史上最全iOS Push技术详解
腾讯技术分享:微信小程序音视频技术背后的故事
腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面
微信多媒体团队梁俊斌访谈:聊一聊我所了解的音视频技术
腾讯音视频实验室:使用AI黑科技实现超低码率的高清实时视频聊天
腾讯技术分享:微信小程序音视频与WebRTC互通的技术思路和实践
手把手教你读取Android版微信和手Q的聊天记录(仅作技术研究学习)
微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)
腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
微信团队分享:Kotlin渐被认可,Android版微信的技术尝鲜之旅
社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等
社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进
社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节
社交软件红包技术解密(四):微信红包系统是如何应对高并发的
社交软件红包技术解密(五):微信红包系统是如何实现高可用性的
社交软件红包技术解密(六):微信红包系统的存储层架构演进实践
社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等
社交软件红包技术解密(十):手Q客户端针对2020年春节红包的技术实践
QQ设计团队分享:新版 QQ 8.0 语音消息改版背后的功能设计思路
微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结
IM“扫一扫”功能很好做?看看微信“扫一扫识物”的完整技术实现
微信团队分享:微信支付代码重构带来的移动端软件架构上的思考
>> 更多同类文章 ……

附录2:更多IM架构方面的文章汇总


[1] 有关IM架构设计的文章:
浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信后台基于时间序的海量数据冷热分级架构设计实践
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
移动端IM中大规模群消息的推送如何保证效率、实时性?
现代IM系统中聊天消息的同步和存储方案探讨
IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?
IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议
IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token
WhatsApp技术实践分享:32人工程团队创造的技术神话
微信朋友圈千亿访问量背后的技术挑战和实践总结
王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等
IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?
腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面
以微博类应用场景为例,总结海量社交系统的架构设计步骤
快速理解高性能HTTP服务端的负载均衡技术原理
子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践
知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路
IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列
微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)
新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践
一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史
阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路
社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等
社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进
社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节
社交软件红包技术解密(四):微信红包系统是如何应对高并发的
社交软件红包技术解密(五):微信红包系统是如何实现高可用性的
社交软件红包技术解密(六):微信红包系统的存储层架构演进实践
社交软件红包技术解密(七):支付宝红包的海量高并发技术实践
社交软件红包技术解密(八):全面解密微博红包技术方案
社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等
社交软件红包技术解密(十):手Q客户端针对2020年春节红包的技术实践
即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?
即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途
多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了
从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路
从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结
IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!
瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)
阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处
从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践
微信后台基于时间序的新一代海量数据存储架构的设计实践
>> 更多同类文章 ……

[2] 更多其它架构设计相关文章:
腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面
快速理解高性能HTTP服务端的负载均衡技术原理
子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践
知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路
新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践
阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史
阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路
达达O2O后台架构演进实践:从0到4000高并发请求背后的努力
优秀后端架构师必会知识:史上最全MySQL大表优化方案总结
小米技术分享:解密小米抢购系统千万高并发架构的演进和实践
一篇读懂分布式架构下的负载均衡技术:分类、原理、算法、常见方案等
通俗易懂:如何设计能支撑百万并发的数据库架构?
多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了
从新手到架构师,一篇就够:从100到1000万高并发的架构演进之路
美团技术分享:深度解密美团的分布式ID生成算法
12306抢票带来的启示:看我如何用Go实现百万QPS的秒杀系统(含源码)
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

标签:微信 IM架构
上一篇:微信团队原创分享:Android版微信的臃肿之困与模块化实践之路下一篇:微信客户端团队负责人技术访谈:如何着手客户端性能监控和优化

本帖已收录至以下技术专辑

推荐方案
评论 3
微信真是牛逼
签名: 周末了,可以浪了
不服不行,真是面面俱到。
借鉴了
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部