微服务分库分表

微服务分库分表

由于数据量过大会导致数据库性能降低,所以使用分库分表将原来独立的数据库拆分为若干数据库,将数据大表拆分成若干数据表,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。

垂直分库

img

概念:以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。

结果:

  • 每个库的结构都不一样;
  • 每个库的数据也不一样,没有交集;
  • 所有库的并集是全量数据;

场景:通过垂直分表性能得到了一定程度的提升,但是还没有达到要求,并且磁盘空间也快不够了,因为数据还是始终限制在一台服务器,单一库内垂直分表解决了单一表数据量过大的问题,但没有将表分布到不同的服务器上,因此每个表还是竞争同一个物理机的CPU、内存、网络IO和磁盘。

垂直分表

img

概念:以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
结果:

  • 每个表的结构都不一样;
  • 每个表的数据也不一样,一般来说,每个表的字段至少有一列交集,一般是主键,用于关联数据;
  • 所有表的并集是全量数据;

场景:系统绝对并发量并没有上来,表的记录并不多,但是字段多,并且热点数据和非热点数据在一起,单行数据所需的存储空间较大。以至于数据库缓存的数据行减少,查询时会去读磁盘数据产生大量的随机读IO,产生IO瓶颈。

分析:可以用列表页和详情页来帮助理解。垂直分表的拆分原则是将热点数据(可能会冗余经常一起查询的数据)放在一起作为主表,非热点数据放在一起作为扩展表。这样更多的热点数据就能被缓存下来,进而减少了随机读IO。拆了之后,要想获得全部数据就需要关联两个表来取数据。但记住,千万别用join,因为join不仅会增加CPU负担并且会将两个表耦合在一起(必须在一个数据库实例上)。

将一个表按字段分成多表,每个表存储其中一部分字段。

解决单一表数据量过大,竞争同一个服务器的问题

数据量访问过大,访问频率过高,分表之后大大降低了通表查询的IO次数。

数据库将数据存在文件(硬盘),引入redis是因为redis将数据存储在内存上,但内存上不能存储大量数据,于是最后一步只能选择分表来降低磁盘IO,提高效率。

水平分库

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4qH1DdDu-1659871012463)(C:\Users\pon18\AppData\Roaming\Typora\typora-user-images\image-20220807180624903.png)]

概念:以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库中。

结果:

  • 每个库的结构都一样;
  • 每个库的数据都不一样,没有交集;
  • 所有库的并集是全量数据;

场景:当一个应用难以再细粒度的垂直拆分,或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时就需要进行水平分库了,经过水平切分的优化,往往能解决单库存储量及性能的瓶颈。但是由于同一个表被分配在不同的数据库,需要额外进行数据操作的路由工作,因此大大提示了系统的复杂度。

水平分表

img

概念:以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。
结果:

  • 每个表的结构都一样;
  • 每个表的数据都不一样,没有交集;
  • 所有表的并集是全量数据;

场景:系统绝对并发量并没有上来,只是单表的数据量太多,影响了SQL效率,加重了CPU负担,以至于成为瓶颈。

分析:表的数据量少了,单次SQL执行效率高,自然减轻了CPU的负担。

分库分表引发的非partition key查询问题

为什么这样做?

这样做的好处是啥?

这样做引发什么问题?

如何解决?

基于水平分库分表,拆分策略为常用的hash法。

端上除了partition key只有一个非partition key作为条件查询

映射法

在库中创建一张partition key和非partition key的映射表

img

基因法

基因法根据user_name查询时,先通过user_name_code生成函数生成user_name_code,再添加xbit基因得到对应的user_id。id生成常用snowflake算法。计算的效率必然高于查询的效率。

img

注:关于xbit基因,例如要分8张表,2^3=8,故x取3,即3bit基因。根据user_id查询时可直接取模路由到对应的分库或分表。

端上除了partition key不止一个非partition key作为条件查询

映射法

img

冗余法

img

注:按照order_id或buyer_id查询时路由到db_o_buyer库中,按照seller_id查询时路由到db_o_seller库中。感觉有点本末倒置!有其他好的办法吗?改变技术栈呢?

后台除了partition key还有各种非partition key组合条件查询

因为有多个非partition key,无法确保查询条件到底是哪个。所以不再考虑改变数据库。

NoSQL法

使用缓存

img

冗余法

通过业务从数据库中取出数据,通过MQ将数据发到运营后台的业务中,让营后台的业务将数据放入运营后台的数据库中。

前端和运营后台分别读取自己的数据库,实现数据双写。

img

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值