这是我参与2022首次更文挑战的第24天,活动详情查看:2022首次更文挑战
数据分区(分片)
定义:每一条数据仅属于某一个特定的分区
每一个分区都可以看作是一个小型数据库
- 分区意味着数据可以分布在不同的机器上,可以提高可扩展性,可以提高系统的吞吐量(例如减少锁冲突等)
- 每一个分区都可以执行查询操作,虽然在复杂大型查询下会比较麻烦,但是可以实现不同节点之间的并行查询
分区与复制
两者可以一起使用,复制可以通过冗余的方式增加系统的可用性,让不同的复制分布于不同的节点上
- 一个节点可能有多个分区
- 一个节点可能有主分区,也可能会有从分区
\
键值数据分区
通过关键字的方式进行数据的访问
海量数据如何进行合理的分区?
分区的目的:
- 数据分布尽可能是的查询负载分布较为均匀
- 与复制结合提高系统的可用性
当分区不均匀的时候(数据倾斜),会导致系统的承载能力没有发挥达到最大
如何进行分区:
基于关键字的分区
-
每个分区有一段连续的关键字范围来规定存储数据的范围\
-
- 可以通过一个关键字快速获取该关键字附近的数据详情
- 每一个节点分配到的关键字数量区间不一定是均匀的,因为数据本身就不一定是均匀的
\
- 根据关键字范围,客户端可以直接对该分区节点进行查询请求
基于关键字哈希的分区
可以起到类似随机分布的作用,如果哈希函数足够随机均匀,可以尽量保证热点的均匀分布
- 分布的随机性导致直接进行顺序(区间)查询的性能下降
不能够完全保证热点分布均匀
- 如果热点就是某一个关键字,那么哈希之后都是一样的,同样会导致倾斜问题
负载倾斜与热点
目前没有完全能够解决负载倾斜问题的方法
-
可以通过哈希的方式减轻热点的问题\
-
- 极端情况可以通过应用层进行监控的方式,进行热点的检测,如果发现是热点那么可以在关键字后面加上随机数的形式防止哈希到同一个分区上
- 后续的读取会变得很麻烦,需要将这些带有关键字的数据都读取出来进行合并,同时还需要记录采用了这种方式的关键字
\
分区与二级索引
二级索引,不是作为数据库的主索引存在,不能保证可以查找到精确的数据,只是用于加速查找过程,可以解释成副缩影
基于分区的二级索引
分区并不是由二级索引所决定的,没有办法直接通过二级索引得到数据的分区位置
文档分区的二级索引
- 每一个分区分别维护自己的二级索引
- 查询时需要将查询语句发送给每一个分区,然后对每一个分区返回的结果进行聚合
- 查询延迟取决于最慢的那个节点,会有延迟放大的问题
基于词条的二级索引分区
-
建立一个全局的索引
-
全局索引也进行多节点上的存储,同样进行分区,将索引本身进行切割,可以使用上述的分区方式进行索引的分区存储
-
在读取上更加高效\
-
- 不会将读请求发送给每一个节点,而是通过二级索引搜索之后发送给指定节点
- 无需聚合操作
\
-
会有写放大\
-
- 单个文档的更新可能会涉及多个二级索引的更新
- 多个二级索引的更新意味着对多个节点的写入操作
- 同步写入的话,同样会有阻塞问题
- 在实际实现中往往是采用异步的方式进行二级索引的更新,这意味着写入并不能够实时的进行查找到
写和读是一对孪生兄弟,对一者有利的时候,可能会对另一者不利