如何解决多个表之间的IO竞争、单机容量问题
拆分后会出现,原来可以进行单库join查询,现在不可以了,需要解决跨库join,还要解决分布式事务等问题。跨库join可以考虑通过如全局表、ES搜索等异构数据机制来实现。数据库垂直拆分中还存在一种宽表拆多个小表的场景,不过一般在设计时就会做这件事情。
按照不同业务拆分后,随着流量的增加,像商品这种读多写少的数据库会遇到读瓶颈,此时就需要使用读写分离来解决,将读和写进行拆分。
随着流量和数据量的增加,单库单表会遇到容量和磁盘/带宽IO瓶颈,单表会随着数据量增长出现性能瓶颈,此时就需要分库、分表,或者分库分表。
分库分表是一种水平数据拆分,会按照如ID、用户、时间等维度进行数据拆分,拆分算法可以是取模、哈希、区间或者使用数据路由表等。
这也导致了前文中说的跨库/跨表join、排序分页、自增ID、分布式事务等问题。对于跨库/跨表join和排序分页,可以对所有表进行扫描然后做聚合,或者生成全局表、进行查询维度的数据异构(比如,订单库按照查询维度异构出商家订单库、用户订单库),再或者将数据同步到ES搜索。自增ID问题可以通过不同表、不同自增步长或分布式ID生成器解决。而分布式事务可以考虑事务表、补偿机制(执行/回滚)、TCC模式(预占/确认/取消)、Sagas模式(拆分事务+补偿机制)等,业务应尽量设计为最终一致性,而不是强一致性。
成都无抵押贷款对于一些特殊数据,我们可以考虑NoSQL,如商品介绍很适合存储在mongodb集群中。
对于互联网应用,尤其是商品系统,读流量可能是写流量的几十倍,而单个商品的查询会非常多,此时,可以考虑使用如Redis进行数据缓存,如下图所示。
部署多个Redis实例,通过Twemproxy并使用一致性哈希算法进行分片,先通过HaProxy进行Twemproxy的负载均衡,然后通过内网域名进行访问。
还有如购物车数据,是用户维度数据,我们完全可以全量存储到KV存储中,如使用Redis进行存储。为了数据的安全性,我们采用了双写架构,如下图所示。
最简单的办法是在多个集群间通过主从来解决,不过主从切换比较麻烦,当主从断开后需要全量更新时恢复较慢。
也可以使用程序双写,实现逻辑比较简单且切换方便。程序双写可以是程序同步双写,写失败其中一个就都失败。这种方式性能差,不适合多机房同步写,也不适合同步写多个集群。
还可以使用异步双写,首先把变更发布到数据总线(如通过MQ实现),然后订阅数据总线变更,异步写其他集群。这种方式的优点是性能好,缺点是异步同步有一定的时延,数据一致性差一些,应考虑使用一致性哈希把用户调度到同一个集群,防止用户刷新多次看到不一样的数据。
实时价格类似于购物车架构,因为查询量非常大,我们会通过挂更多的从来扩展读的能力,如下图所示。
Redis使用内存复制缓存区个人小额信用贷来存放主从之间要同步的数据。当主从断开时间较长时,复制缓冲区达到阈值,此时旧缓存数据会被丢弃,此时断开的主从进行同步时将会全量复制。Redis也没有提供类似于mysql binlog的机制。
到此应用拆分和数据库拆分就介绍完了。应用扩容可以通过部署更多的应用实例来解决,无法部署更多的实例时,就需要考虑系统拆分或者重新架构。而数据库扩容首先是硬件层面,然后按照业务进行垂直拆分,接着进行水平拆分,最后根据流量场景进行读写分离,还可以将读流量分流到NoSQL上。
本文地址:如何解决多个表之间的IO竞争、单机容量问题 _http://longshunzhuangshi.com/jianzhanzixun/231.html 本文tag标签:如何解决多个表之间的IO竞争、单机容量问题
上一篇:搜索引擎在乎垃圾
下一篇:网站收录查询方法