游戏资讯 app(He3DB 架构设计05)

wufei123 发布于 2023-11-30 阅读(501)

第4层:高性能存储层:写流程:HE3DB只有主节点能够提供写服务,当用户提交事务时,只有对应的WAL日志完成持久化后,事务才能提交成功HE3DB中主备没有通过流复制同步日志,而是把WAL日志写入高性能存储层,通过RAFT算法,只要多数派完成日志持久化,就能够完成日志持久化,从而事务完成提交状态机设计:当日志提交后,apply日志到状态机,由状态机建立数据页+WAL的链表关系,并在内存中维持全量链表关系,以及基于时间维度,访问频率,缓存相关数据页以及对应的WAL读流程:如果He3FS CLIET 读取的数据页计算引擎本地盘没有命中,会调用高性能存储层读取数据页以及基于链表读取相关的WAL日志,由HE3CLIET回放成对应的版本数据页,高性能存储层由状态机提供读数据服务,如果数据页在状态机内存命中,根据内存中的链表关系,找到相关WAL日志,一起返回给HE3 CLIENT。

第5层:低性能存储层使用S3持久化存储所有的数据,HE3DB选型JUICEFS 作为冷数据持久层,挂载到高性能存储层实例中,主要用于状态机数据的持久化为什么选型JUICEFS?主要因为他的理念跟我们匹配,并且提供完备的文件系统接口,HE3DB第一版选择使用JUICEFS能够帮助我们节省大量的开发时间,目前我们也完成了JUICEFS几乎所有的核码分析,后续会陆续分享出来。

低性能存储层对应的数据:高性能存储层,收到的WAL以及链表关系的持久化,会保存到juicefs(也就是S3中)数据页,数据页由推进节点产生,推进节点跟备节点很像,持续读取WAL日志,异步回放成对应的数据页,推进节点的目的:一是产生新的数据页,或者删除数据页;二是保证数据新足够新,不至于链表关系过长,影响读取性能链表关系:状态机回放日志时,最重要的工作就是更新链表关系,当内存无法保存所有的链表关系时,由持久化到共享存储中

一些问题?每一层数据如何同步,也就是底层数据页发生更新,是否需要同步更新每层对应数据PAGE,是否影响数据正确性?当推进节点更新数据页后,并不需要立马同步更新各个缓存中的数据页,因为实现数据页多版本,每一层保存了对应版本的WAL日志,所以不需要立马更新每一层数据页

链表关系如何同步?首先计算引擎基于缓存的数据页,会维护最新的链表关系,如果读取的数据页没有在计算层命中,从高性能存储层读取对应基础页以及链表关系,WAL日志并更新计引擎链表关系链表如何更新?HE3 CLIENT会自动维护链表关系的最新版本,并定期跟高性能存储层交互,保证每个链表的长度最优。

扩展性:计算层,高性能存储层,低性能持久层能够基于业务负载独立完成扩缩容如果希望增加读吞吐能力的话,可以增加备节点,并配置对应的内存,缓存的热数据如果备机数量过大,导致高性能存储层读负载过大,可以增加leaner节点,提供读服务如果低性能存储层容量过小,可以考虑增加节点,线性增加容量。

工程实践一些点:计算引擎,推进节点基于PG改造高性能存储层:使用RUST 开发,使用异步编程,无锁化设计低性能存储层:基于juicefs改造,对接到raft 状态机中间件:使用golang开发,支持PG协议,重点一致性读,负载均衡,连接池设计

架构的演进方向:新硬件引入:HE3DB架构的设计,从开始之初,就把可持续演进作为最重要的目标,未来高性能存储层会考虑引入新硬件,来提升性能以及吞吐能力,进一步提高性能上限高性能存储层RAFT算法未来是否会考虑支持muti-group?

当前计算引擎是一主多备,所以高性能存储层为了保证架构的简单性以及服务组件的最小化,使用single raft group提供高可用如果使用multi-group,必须提供额外的组件做协调服务,开发周期长。

后期高性能存储层会同时提供多个cluster写服务,到时会演进到multi-group,当前single raft group 主要为了尽快实现以及性能指标论证目的当前计算引擎是一主多读,高性能存储引擎也是一主多读,所以一一对应部署的话,高性能存储引擎不会成为瓶颈

亲爱的读者们,感谢您花时间阅读本文。如果您对本文有任何疑问或建议,请随时联系我。我非常乐意与您交流。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。