天天看点

《大规模分布式存储系统》第九章 分布式存储引擎

  • 概述

    本章主要介绍 OceanBase 分布式引擎层各模块的实现细节。涉及到数据结构、RPC开发框架、内存优化等细节,即使介绍的较为详细但是对于深入学习还是不够的,只能在日常工作中大量的实践才能充分体会。本部分只以个人视角,记录较为重要的技术。

  • 公共模块(基础库)

内存管理:全局的内存池(64Kb、2MB两种),每个线程单独的内存管理。全局内存池好处有两个,第一是可以统计各模块的内存使用情况,第二是方便调试,空闲内存用特殊值填充,异常情况下及时core。在系统开发初期,满足可控性 和 减少内存碎片的需求,虽然技术不那么高深(效率差等问题)。

数据结构

    HashMap:位锁,一个桶一个位级别的锁。延迟初始化,每次初始化一段桶,省时高效。

    B树:增加并发性能、写时复制技术更新时不影响读、删除操作通过叶子节点追加删除标记实现,好处是不改变索引。

    锁:互斥锁 与 共享锁机制公用一个数据结构,通过标志位区分,且可以互相转换(更高效)。

任务队列:单生产者多消费之,单纯的任务队列,锁会成为瓶颈。解决方案,消息队列中预先分配好线程号,消费者每次只会去指定的槽位check,减少了锁的占用时间。

  • RootServer实现机制

    RootTable记录了子表的元信息,使用了写时复制技术,提高读的性能。持有UpdateServer的Token,如果RootServer本身升级,租约过期,无法进行写请求,暴漏一个接口,可以让UpdateServer持有Token的时间较长(30min)。

    注:期间主挂了呢?还需要更完备的方案。

  • UpdateServer实现机制

    操作日志通过Direct IO写入磁盘,避免感染系统缓存,因为系统缓存针对的主要是数据,可以提高性能。MemTable采用的数据结构是B树,叶子节点是链表,记录了修改日志。所有的表格公用一个SSTable。网络框架,Tbnet使用的是读写单线程,pusk、pull任务队列,然后分发给工作线程,上下文切换成为性能瓶颈,通过epoll + 多线程直接调用业务逻辑,减少上下文切换。

  • ChunkServer实现机制

    CPU与磁盘IO实现异步,通过双缓存实现。定期合并需要控制速度,请求分级、ChunkServer增加随机延时、控制每次合并的行数。

  • 消除更新瓶颈

    数据旁路导入(SSTable加载),通过MapReduce等技术(主要是OLAP业务)跑出子表并生成相关SSTable文件,传输到ChunkServer上,批量执行加载操作,然后汇报给RootServer(具体实现还是较为复杂的,涉及到各种容错、完备性校验等等)。UpdateServer可以通过主键hash为集群,跨主键事务需要2PC。需要明确的是,针对OLTP业务尤其天生的天花板,例如,全球50亿人,每天又五分之一产生一笔交易,也仅仅10亿条数据。

继续阅读