5

写入热点打散的问题

 3 years ago
source link: https://www.zenlife.tk/hot-region.md
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

写入热点打散的问题

2021-01-27

热点打散问题,可能是分布式数据库最不喜欢遇到,但是又经常会遇到的问题之一。

理想的状态,对于分布式的数据库,只要一直加机器,就可以分担负载分散流量,总是 scalable 的。然而在存在热点的情况下,就 scalable 不起来了,负载总是打到很固定的节点上面,怎么拆分都不管用。

比较典型的一个例子比如自增主键,编码之后对应都的都是紧紧相邻的一块区域,然后就形成热点了。还有就是时间类型,往往时间相关的数据都是比较连续的,也是容易造成热点。业务场景容易遇到热点问题的,比较典型的比如删数据,按时间过期这种。MVCC 的引擎,增删改查里面,最重的操作其实是删除,因为删除是追加新版本数据,然后再做 GC Compaction,而 GC 这个东西是 LSM 类引擎里面最影响性能的。热点数据的删除,再跟 GC 一起,很容易造成延迟的上升,响应时间的抖动。

对于自增主键这一类热点问题,我们有做过处理,比如用生成随机数作主键,实现数据打散。

我们的数据库是是多层的映射,先把值编码到一层虚拟的 key-value 的范围,这是第一层。然后再把 key-value 划分成一块一块的 range,这可以算第二层,这里的划分是动态的划分的,而不是均匀划分。range 再映射到不同的物理节点上面,这算第三层,这个映射关系由一个中心化的调度器来管理。

从值到 key-value 的编码,这一层的编码规则是写死了的,所以这一层不可变了。连续的值打不散,是因为它们在编码后仍然连续,所以打不散。

在数据分布的映射那一层,我们按 range 切分,并且从虚拟到 range 到物理的节点,这一层是可以动态的,调度的节点随时都在调整。一个 range 内数据越来越多以后,就被切分成多个 range 来管理了。

在 range 到物理节点映射那里,可以做一个打散功能,但是这个打散只能是基于 range 的。对于连续的值,基于 range 并不容易打散。还有一个问题是数据分布,即使提供了这一层的打散的机制,我们无法预估数据的分布情况,实际使用中也非常不灵活。

不改编码方式,用随机数当主键,只能处理部分场景。比如主键通过随机数生成,容易实现打散,但是索引就不行。索引一定是根据值来生成的,而时间这类值的特点,生成出来的索引自然是连续的。这个是我真正最想解决的点,希望有什么通用的热点打散的解决方案!

脑洞一下,是否可以在 值 => kv range 映射的过程,做一点手脚。自然想到了按 hash。但是如果按 hash 只能应对点查,范围查询会无法处理。 并且编码需要是可比较的,比如查询请求是 key > 32,对应的 range 也要能根据查询算出来 kv 空间对应的 range。所以用 hash 映射好像不太行得通。

没想到解决方案,先把问题记录下来...


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK