1000 万与两亿数据读写对比
一个查询执行太久会导致有大量的连接被占用,达到连接上限就会报错.
a. 比如一共 2亿数据(序号(id)1-2 亿),分成两个表; 序号(id)1-1 亿的数据在一个表,序号 1 亿-2 亿的在一个表
ⅰ. 缺点:数据不均
1. 假如只有1 亿零 1 条数据,按照这个分库的方法,那么第一个库有一亿数据量,另一个只有一条数据
ⅱ. 无法实现数据的动态分配
ⅰ. 比如: 一共有 5 台服务器(实例):根据用户的 id(或者其他字段哈希成 int)%5(实例的数量)=对应的数据库
1. 优点: 解决了数据动态分配的问题
2. 缺点:
3. 容易造成数据不均衡(比如大部分的数据都在其中的一两个节点)
4. 拓展性差: 如果要增加或者减少实例的数量,需要重新配置,加载实例
ⅰ. 固定哈希环(2^16)16384 个槽位
ⅱ. 每个节点均匀的分布在哈希环上面
ⅲ. (假设一共 10000 个大小的哈希环(其实不止),一共部署 5 个实例,哈希值在 0-2000 的数据储存到节点 1;2000 到 4000 的数据储存在节点 2; 以此类推,占满 整个哈希环
1. 问题(数据不均衡):数据的哈希值90% 都哈希再 0-2000 ,那么 90% 的数据储存在第一个哈希环,造成严重的数据不均衡
2. 解决方案:虚拟节点
a. 90% 的数据都哈希再 0-2000 的范围内,那么把 0-2000 的数据进行拆分,按 400一格分成 5 格,那么就可以插入 4 个虚拟节点 ,
b. 虚拟节点并不是真正的,而是拦截数据将其转移到真正的节点上
ⅰ. 比如 400 处有一个节点指向 4000 的真实节点(槽),那么哈希值 0-400 的数据将被虚拟节点拦截,并储存到真实节点4000中,解决节点负载不均的问题
b. 优点:
ⅰ. 解决数据动态分配,数据均匀分表,实例拓展问题
a. 主要是三种分片方案
ⅰ. 范围
ⅱ. 哈希
ⅲ. 标签(按照不同的标签将数据放到不同的实例)
■ Chunk(数据块): 数据在每个分片上的基本单位。每个 Chunk 包含一段连续的范围数据(基于分片键)。
■ Balance(均衡): 是 MongoDB 自动调整数据分布的过程,即通过迁移 Chunk 来保持分片之间的均衡。
■ Chunk 的拆分
● 一个块最大 64MB,超过最大值就自动分成两个块,没有数据的迁移,很快
■ 数据均衡的一个重要组成部分是 Chunk 的迁移。MongoDB 会根据数据量和负载情况定期移动 Chunk,确保所有分片的存储容量保持平衡。
● 过程
当某个分片的 Chunk 数据量过大或某些分片的数据量较小,MongoDB 会通过均衡器(Balancer)将 Chunk 从一个分片迁移到另一个分片。
迁移是自动进行的,MongoDB 会确保迁移过程中数据的完整性和一致性。
迁移操作会在后台执行,尽量减少对客户端请求的影响。
优点: 数据的均衡与负载均衡
缺点: 是内部线程实现的,有一定的性能消耗
分库后,数据可能分布在不同的库中。例如:
一个订单系统,订单信息和用户信息被拆分到不同的库。如果需要在一个事务中同时更新订单状态和用户余额,就涉及跨库事务。
对表/库进行水平拆分后就无法保持强唯一约束了
使用 UUID 生成唯一标识。
优点:保证全局唯一;缺点:UUID 长度大,索引性能较差。
基于时间戳生成全局唯一 ID(如 Twitter 的 Snowflake 算法)。
优点:高效,生成的 ID 有序;缺点:依赖外部服务。
设置每个库的自增 ID 起始值和步长。例如:
库1:1, 3, 5…
库2:2, 4, 6…
优点:实现简单;缺点:不适用于动态扩容。
问题
分库后,复杂查询(如多表 JOIN 或聚合操作)变得困难。例如:
查询某用户的所有订单和支付记录,但订单和支付信息在不同库中。
分库分表可能导致数据访问集中于某些分片。例如:
用户按 ID 分片,但某些大客户的操作频繁集中到一个库,造成热点
参考:
https://cloud.tencent.com/developer/article/1901963
https://www.cnblogs.com/chengxy-nds/p/16924305.html
https://cloud.tencent.com/developer/article/1843987
提示:请勿发布广告垃圾评论,否则封号处理!!