数据库管理 2022-09-18
第三十六期 集中式向分布式转变要付出什么
本周我所在的区域终于算是解封了,可以下楼出去晃悠了,当然还是有范围限制,相信很快整个成都都能解封了。
上一期的文章有幸被一些业内大佬看到了,对其中一句话提出来批评指正:“所以说当你听说换一种数据库几乎不用动代码、动设计的时候,请记住,除非是数据库来匹配你的需求,否则几乎不可能”,大佬们认为需要吧“几乎”去掉。
继续,本期属于扯淡!
1 分布式数据库典型架构
集中式数据库就不谈了,包括一般的主从读写分离架构。
一般来说分布式数据库本身逻辑架构会分为三层:分发层、元数据层、数据层。
数据实际是存放在数据层的每个分片中的,每个分片包含若干个节点,每个节点之间是副本关系。
数据是怎么分步在每个分片上则会存放在元数据层。
数据库请求会先到分发层,根据元数据层的内容将对应请求分发到具体的数据层分片,分片完成计算后再将结果反馈至分发层进行汇总。
2 CAP
CAP理论,指的是在一个分布式系统中,Consistency(一致性)、Availability(可用性)、Partition Tolerance(分区容错性),不能同时成立。
因为有CAP理论,大多数的分布式数据库都使用的最终一致性来确保数据安全和性能之间的平衡,即在一个分区内大多数节点返回成功即判定这个分区数据操作成功。当然在某次国产数据库沟通中,一个比较出名的金融级分布式数据库的售前说他们是强一致性,并且能够达到CAP中间那一块,这是不可能的(没有几乎)。
3 最终一致性的代价
假如一个分片有5个节点(别问我为啥不举例双数节点,说就是容易脑裂),假如有3个节点数据操作返回成功了,另外两个节点没有成功,整个集群已经判断这个数据操作成功了。而在这个时间点,返回成功的这3个节点正好挂掉了,另外两个节点没有这份数据,那么就会造成数据丢失,当然一般来说集群还是有其他方法比如日志来恢复这些数据。
同样的情况,也是这个时间点,要对刚刚操作的数据进行查询,要么可能出现从两个没成功的节点获取错误或者直接没数据,要么就是在集群层面根据操作反馈将查询请求分发到成功节点,在分片越多,节点越多的情况下这样的操作就会消耗更多的资源。
4 分布式数据库的逻辑设计
4.1 单表
即数据量及访问量都很小的表,让这种表仅存在于某个分片内,无需将表数据分布在各个分片内。
4.2 分片表
即是将表的数据按照一定规则分步到各个分片内,通俗点的解释就类似于分区表,只不过每个分区在每个分片内。一般的分布式数据库分片表设计要求,是表必须有主键和分片键(即根据某列的值进行分片),且分片键必须包含在主键内。为了尽可能的减少在没必要的分片上进行数据操作,在查询时墙裂建议带上分片键。
4.2.1 父子表
以订单系统为例,如果订单主表和订单详情表分布在不同分片内,那么联查某个订单详细内容时就会出现需要将两张表的内容通过网络传输到一个分片(还可能是某个节点)在一个实例内存中进行计算(这样性能最好)。因此在类似的需求中,需要将订单ID做主外键关联以确保关联数据在同一分片内,可以在一个实例内进行计算,防止网络传输。
4.3 复制表
其实还是父子表那节的问题,要避免跨分片(实例)的数据网络传输来实现查询计算,那么还是以订单系统为例,客户表和商品表作为全局数据,其涉及的数据可能覆盖到所有的分片上,那么就需要复制表来实现。复制表即是在每个分片维护一个数据相同的表,当然分片、节点越多,维护成本越高。(有个脑残的想法,如果这个例子中的客户表、商品表本身也很大,那么可以通过分片内表分区提高性能,当然设计难度更高)
5 设计变更
从传统的集中式数据库更换成分布式数据库,首先需要做到的一点就是对数据库逻辑结构设计的彻底颠覆,需要根据分布式的特性进行重新设计,同时要考虑到CAP理论带来的各种风险。另一方面,在使用分布式数据库以后,再进行需求变更特别是涉及分片表的时候可能会很难对表结构进行变更。
6 分片精度问题
在分布式数据库进行查询,如果是等值、范围查询,那么没啥问题,但是比如类似TOP3的查询则可能出现一些问题,距离数据分步如下:
值 | 分片1 | 分片2 |
---|---|---|
A | 6 | 6 |
B | 4 | 2 |
C | 4 | 1 |
D | 3 | 3 |
如果只是单纯将TOP3的SQL分发到每个分片上执行就会从分片1得到:A(6),B(4),C(4);分片2得到:A(6),D(3),B(2)。结果汇总TOP3:A(12),B(6),C(4)。但是从实际数据来看,TOP3应该是A(12),B(6),D(6)。其实这是分布式数据库的通病(在分析类系统中其实可以通过一些手段尽可能减小精度差异,但在OLTP系统中则需要精确数据),一旦涉及排序,就需要在所有分片将所有数据计算后再跨分片进行统计,因此我们看到很多分布式数据库是需要非常大的内存(另一种说法是,咱们的数据库不适合数据量小的业务),而目前为了加速各类分析,实现HTAP,各类数据库里面也加上了内存列式存储来加速(总之就是内存小了不行)。
7 其他的一些问题
本节内容是我理解或者我听到过的一些问题:
- 当分片数据量不均匀的时候,需要进行重新分片,往往对于集群的性能消耗是灾难级的,无论是CPU、内存还是磁盘、网络
- 你需要跟多的服务器尤其是内存来承载业务(这个有可能是几十倍上百倍的增长),而且集群的横向扩展要看网络能否支撑
- 开发人员需要重新数据分布式特性,来变更应用
- 除去跨分片排序查询的精度问题,跨分片join table也是一种很恶劣的情况,同样需要占用相当多的内存和网络资源(感谢祁总的补充!)
- 等等等等,欢迎大佬指正
总结
还是不晓得写了些啥!