您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
用“分区”来面对超大数据集和超大吞吐量
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
用“分区”来面对超大数据集和超大吞吐量
wy****
2025-11-21
IP归属:北京
163浏览
### 1\. 为什么要分区? **分区(partitions)** 也被称为 **分片(sharding)**,通常采用对数据进行分区的方式来增加系统的 **可伸缩性**,以此来面对**非常大的数据集或非常高的吞吐量**,避免出现热点。 分区通常和复制结合使用,使得每个分区的副本存储在多个节点上,保证数据副本的 **高可用**。如下图所示,如果数据库被分区,每个分区都有一个主库。不同分区的主库可能在不同的节点上,每个节点可能是某些分区的主库,同时是其他分区的从库。  #### 1.1 一致前缀读 分区也会由于复制延迟而产生问题,我们先来看下图中的例子,是Poons先生和Cake小姐的对话:  Poons先生先问: "How far into the future can you see, Mrs.Cake?" Cake小姐回答说: "About ten seconds usually, Mr.Poons." 正常情况下,这段对话是有因果关系的(先问后答)。但是对于观察者,他看到的顺序却是先得到了答案,再看到了问题,这就是在分区数据库中,因复制延迟而产生的特殊情况。 为了避免这种混乱,我们就需要保证 **一致前缀读**:如果一系列写入按某个顺序发生,那么任何人读取这些写入时,也会看见它们以同样的顺序出现。一种解决方案是,确保任何因果相关的写入都在相同的分区。 ### 2\. 该怎么分区? 分区的目的是将数据和负载均匀的分布到各个节点上,理论上10个节点能够处理10倍的数据量和10倍单节点的读写吞吐量。 但是如果分区不均,那么就会出现一些分区有更多的数据或读写,我们称之为 **偏斜**,这会使得分区后并没有得到很大的效率提升。在极端情况下,所有的负载如果都落在一个分区,使得该分区负载过高,我们称之为 **热点**。 所以,为了避免偏斜和热点的产生,以键值数据的分区为例,讨论如何将数据分区做得妥当。 #### 2.1 根据键的范围进行分区 我们可以根据键值的范围进行分区,比如说我们以26个英文字符划分26个分区,之后根据键值首字母对它们进行分区。通常情况下,键值并不是均匀分布的,这会造成按照首字母分区之后,发生数据偏斜。为了均匀分配数据,分区的边界需要根据数据分区的实际情况再进行调整。 #### 2.2 散列分区 一个好的散列函数可以将数据均匀分布,避免发生偏斜。但是这也带来了问题:我们没有办法再进行高效的范围查询。 ### 3\. 热点消除 避免热点最简单的方法是将数据记录进行散列分区,记录因此会在所有节点上平均分配。 但是它并不能完全避免热点的产生,因为如果所有的读写操作都是针对同一个键的话,那么所有的请求还是会被路由到同一个分区。比如说有一个百万粉丝的博主发布动态,该动态根据博主ID的键值进行分区,如果此时有大量的粉丝对该动态进行互动,那么哈希策略会把这些请求都路由到同一个分区进行操作,发生热点事件。 其实,我们还可以在该热点键上再进行分区,以避免热点:在主键的最后拼接随机数,两位十进制的随机数就能把一个主键分成100个不同的主键,从而存储在不同的分区中,这就完成了热点消除。但是主键被分割后,任何读取工作都必须在每次读取时将所有的数据拉出去合并到一起再返回结果。 ### 4\. 分区再平衡 如果保存某分区数据的服务器故障,需要使用其他服务器接管或想将目前的服务器换成性能更好的服务器,那么就需要进行 **分区再平衡**。 **分区再平衡** 是将负载从集群中的一个节点向另一个节点移动的过程。执行再平衡需要满足以下要求: * 再平衡期间,数据库应该继续接受读取和写入 * 节点之间只移动必须的数据,以便快速再平衡,并减少网络和磁盘的IO负载 * 再平衡之后,负载应该在集群中的节点之间公平地共享 比较简单的再平衡分区策略是选择 **固定数量的分区**,当节点数量增加时,可以从原节点中 **窃取** 一些分区(当节点数量减少时,则发生相反的情况),如下图所示:  在这种配置中,分区的数量通常在数据库第一次建立时确定,操作比较简单,之后不会改变,因此你需要选择足够多的分区以适应未来的增长。但是,每个分区也有管理开销,所以选择太大的数字会适得其反。 除此之外也可选择 **动态分区**,根据配置的分区大小,当超过该阈值时,可以将该大分区分割成两个小分区,能够使 **分区数量适应总数据量**。在大型分区拆分后,可以将其中的一半转移到另一个节点上,以平衡负载。 还有一种 **根据节点数增加来进行分区** 的方法:每个节点上有固定的分区数,当节点增加时,分区将变小,新增的节点会从原有节点的分区中随机进行拆分,最终这个新节点获得公平的负载份额。 分区再平衡可以 **手动执行** 也可以 **自动执行**。自动再平衡比较方便,因为不需要人工维护,但是它的执行过程是不可预测的:再平衡时将大量数据集从一个节点转移到另一个节点的过程中可能会产生很大的网络开销,这会使得该服务器对请求响应的性能降低,对用户的体验和生产造成负面影响。所以再平衡的过程有人参与是一件好事,这样能防止发生运维问题。 ### 5\. 请求路由(服务发现) 当我们已经将数据进行分区后,如何才能知道用户想要的数据在哪个节点上?这可以概括为是一个 **服务发现** 的问题。为了解决这个问题,可以通过如下图所示的三个方案  1\. 允许访问所有的节点,如果第一个访问的节点有该键值,则处理该请求,否则将该请求转发到适当的节点上,这个方法避免了使用注册中心中间件,但是实现比较复杂 2\. 使用分布式的协调服务,用户将所有的请求发送到路由层,由路由层将该请求转发到合适的节点 3\. 要求用户(客户端)自己知道分区和节点的分配 但是这其中还隐藏着一个问题:**作出决策的组件(节点之一、路由层或客户端)是如何了解数据在节点间的分配变化的**?这就需要一个独立的协调服务,比如使用 zookeeper 来跟踪元数据,如下图所示  每个节点都会在 zookeeper 中进行注册,zookeeper 中维护有节点到各个分区的可靠映射,负责决策的组件在 zookeeper 中订阅这个消息。当分区分配发生改变时,zookeeper 就会通知负责决策的组件更新路由信息,使其保持在最新的状态。 除此之外也可以在各个节点间采用 **流言协议** 来传播集群状态的变化,这样每个节点都维护有最新的数据路由方案,当其中一个节点收到请求时,会将其转发到合适的分区节点上(对应服务发现的方案一)。 --- ### 巨人的肩膀 * 《数据密集型应用系统设计》:第六章 分区
上一篇:三十分钟入门基础Go——Java小子版
下一篇: RAG 分块策略:从原理到实战优化,喂饭级教程不允许你踩坑
wy****
文章数
47
阅读量
22083
作者其他文章
01
高性能MySQL实战(一):表结构
最近因需求改动新增了一些数据库表,但是在定义表结构时,具体列属性的选择有些不知其所以然,索引的添加也有遗漏和不规范的地方,所以我打算为创建一个高性能表的过程以实战的形式写一个专题,以此来学习和巩固这些知识。1. 实战我使用的 MySQL 版本是 5.7,建表 DDL 语句如下所示:根据需求创建 接口调用日志 数据库表,请大家浏览具体字段的属性信息,它们有不少能够优化的点。CREATE TABLE
01
缓存之美:从根上理解 ConcurrentHashMap
本文将详细介绍 ConcurrentHashMap 构造方法、添加值方法和扩容操作等源码实现。ConcurrentHashMap 是线程安全的哈希表,此哈希表的设计主要目的是在最小化更新操作对哈希表的占用,以保持并发可读性,次要目的是保持空间消耗与 HashMap 相同或更好,并支持利用多线程在空表上高效地插入初始值。在 Java 8 及之后的版本,使用 CAS 操作、 synchronized
01
由 Mybatis 源码畅谈软件设计(六):Interceptor 拦截器的设计
本节我们来介绍 Mybatis 的拦截器 Interceptor,它依靠 @Intercepts 和 @Signature 注解驱动,配置拦截器的切入方法,这种声明方式非常直观,能够准确的知道每个拦截器的作用范围。而且它是非侵入性的,采用了 动态代理模式,在不修改原有逻辑的前提下便能实现功能的扩展,遵循 开闭原则。Spring 框架中的 AOP 也采用的是同样的思想,但是它引入了很多概念(切面、连
01
缓存之美:万文详解 Caffeine 实现原理(上)
由于神灯社区最大字数限制,本文章将分为两篇,第二篇文章为缓存之美:万文详解 Caffeine 实现原理(下)文章将采用“总-分-总”的结构对配置固定大小元素驱逐策略的 Caffeine 缓存进行介绍,首先会讲解它的实现原理,在大家对它有一个概念之后再深入具体源码的细节之中,理解它的设计理念,从中能学习到用于统计元素访问频率的 Count-Min Sketch 数据结构、理解内存屏障和如何避免缓存伪
wy****
文章数
47
阅读量
22083
作者其他文章
01
高性能MySQL实战(一):表结构
01
缓存之美:从根上理解 ConcurrentHashMap
01
由 Mybatis 源码畅谈软件设计(六):Interceptor 拦截器的设计
01
缓存之美:万文详解 Caffeine 实现原理(上)
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号