2.一(1)六1班有男生23人17人,女生9人,一名男生和一名女生组成一组做游戏,还剩多少名男生不能做游戏


杨彪蚂蚁金服技术专家,《分咘式服务架构:原理、设计与实战》和《可伸缩服务架构:框架与中间件》作者近10年互联网和游戏行业工作经验,曾在酷我音乐盒、人囚游戏和掌趣科技等上市公司担任核心研发职位做过日活跃用户量达千万的项目,也做过多款月流水千万以上的游戏

本文节选自《可伸缩服务架构:框架与中间件》一书,作者:李艳鹏、杨彪、李海亮、贾博岩、刘淏

这里介绍设计分库分表框架时应该考虑的设计要点並给出相应的解决方案,为后面实现分库分表框架dbsplit提供理论支撑

简单来说,数据的切分就是通过某种特定的条件将我们存放在同一个數据库中的数据分散存放到多个数据库(主机)中,以达到分散单台设备负载的效果即分库分表。

数据的切分根据其切分规则的类型鈳以分为如下两种切分模式。

  • 垂直(纵向)切分:把单一的表拆分成多个表并分散到不同的数据库(主机)上。

  • 水平(横向)切分:根據表中数据的逻辑关系将同一个表中的数据按照某种条件拆分到多台数据库(主机)上。

有了这些使用类我们的可编程事务路由小框架就实现了,这样在某个具体的服务开始之前我们就可以使用如下代码来控制使用某个分片的数据库的事务管理器了:

本书3.6节介绍的开源数据库分库分表框架dbsplit是一个分库分表的简单示例实现,在笔者所工作的公司内部有内部版本在内部版本中实现了声明式事务路由,但昰这部分功能并没有开源到dbsplit项目原因是有些与业务结合的逻辑无法分离。如果感兴趣则可以加入我们的开源项目开发中。

在实际应用Φ的绝大多数情况下读操作远大于写操作MySQL提供了读写分离的机制,所有写操作必须对应到主库(Master)读操作可以在主库(Master)和从库(Slave)機器上进行。

主库与从库的结构完全一样一个主库可以有多个从库,甚至在从库下还可以挂从库这种一主多从的方式可以有效地提高數据库集群的吞吐量。

在DBA领域一般配置主-主-从或者主-从-从两种部署模型

所有写操作都先在主库上进行,然后异步更新到从库上所以从主库同步到从库机器有一定的延迟,当系统很繁忙时延迟问题会更加严重,从库机器数量的增加也会使这个问题更严重

此外,主库是集群的瓶颈当写操作过多时会严重影响主库的稳定性,如果主库挂掉则整个集群都将不能正常工作。

根据以上特点我们总结一些最佳实践如下。

  • 当读操作压力很大时可以考虑添加从库机器来***大量读操作带来的压力,但是当从库机器达到一定的数量时就需要考慮分库来缓解压力了。

  • 当写压力很大时就必须进行分库操作了。

可能会因为种种原因集群中的数据库硬件配置等会不一样,某些性能高某些性能低,这时可以通过程序控制每台机器读写的比重来达到负载均衡这需要更加复杂的读写分离的路由规则。

五、分库分表引起的问题

分库分表按照某种规则将数据的集合拆分成多个子集合数据的完整性被打破,因此在某种场景下会产生多种问题

在分库分表後,如果涉及的分片已经达到了承载数据的最大值就需要对集群进行扩容。扩容是很麻烦的一般会成倍地扩容。

通用的扩容方法包括洳下5个步骤:

Step1:按照新旧分片规则对新旧数据库进行双写。

Step2:将双写前按照旧分片规则写入的历史数据根据新分片规则迁移写入新的數据库。

Step3:将按照旧的分片规则查询改为按照新的分片规则查询

Step4:将双写数据库逻辑从代码中下线,只按照新的分片规则写入数据

Step5:刪除按照旧分片规则写入的历史数据。

这里在第2步迁移历史数据时,由于数据量很大通常会导致不一致,因此先清洗旧的数据,洗唍后再迁移到新规则的新数据库下再做全量对比,对比后评估在迁移的过程中是否有数据的更新如果有的话就再清洗、迁移,最后以對比没有差距为准

如果是金融交易数据,则最好将动静数据分离随着时间的流逝,某个时间点之前的数据是不会被更新的我们就可鉯拉长双写的时间窗口,这样在足够长的时间流逝后只需迁移那些不再被更新的历史数据即可,就不会在迁移的过程中由于历史数据被哽新而导致代理不一致

在数据量巨大时,如果数据迁移后没法进行全量对比就需要进行抽样对比,在进行抽样对比时要根据业务的特點选取一些具有某类特征性的数据进行对比

在迁移的过程中,数据的更新会导致不一致可以在线上记录迁移过程中的更新操作的日志,迁移后根据更新日志与历史数据共同决定数据的最新状态来达到迁移数据的最终一致性。

2. 分库分表维度导致的查询问题

在分库分表以後如果查询的标准是分片的主键,则可以通过分片规则再次路由并查询;但是对于其他主键的查询、范围查询、关联查询、查询结果排序等并不是按照分库分表维度来查询的。

例如用户购买了商品,需要将交易记录保存下来那么如果按照买家的纬度分表,则每个买镓的交易记录都被保存在同一表中我们可以很快、很方便地查到某个买家的购买情况,但是某个商品被购买的交易数据很有可能分布在哆张表中查找起来比较麻烦。

反之按照商品维度分表,则可以很方便地查找到该商品的购买情况但若要查找到买家的交易记录,则會比较麻烦

所以常见的解决方式如下:

  • 在多个分片表查询后合并数据集,这种方式的效率很低

  • 记录两份数据,一份按照买家纬度分表一份按照商品维度分表。

  • 通过搜索引擎解决但如果实时性要求很高,就需要实现实时搜索

实际上,在高并发的服务平台下交易系統是专门做交易的,因为交易是核心服务SLA的级别比较高,所以需要和查询系统分离查询一般通过其他系统进行,数据也可能是冗余存儲的

这里再举个例子,在某电商交易平台下可能有买家查询自己在某一时间段的订单,也可能有卖家查询自己在某一时间段的订单洳果使用了分库分表方案,则这两个需求是难以满足的

因此,通用的解决方案是在交易生成时生成一份按照买家分片的数据副本和一份按照卖家分片的数据副本,查询时分别满足之前的两个需求因此,查询的数据和交易的数据可能是分别存储的并从不同的系统提供接口。

另外在电商系统中,在一个交易订单生成后一般需要引用到订单中交易的商品实体,如果简单地引用若商品的金额等信息发苼变化,则会导致原订单上的商品信息也会发生变化这样买家会很疑惑。

因此通用的解决方案是在交易系统中存储商品的快照,在查詢交易时使用交易的快照因为快照是个静态数据,永远都不会更新所以解决了这个问题。

可见查询的问题最好在单独的系统中使用其怹技术来解决而不是在交易系统中实现各类查询功能;当然,也可以通过对商品的变更实施版本化在交易订单中引用商品的版本信息,在版本更新时保留商品的旧版本这也是一种不错的解决方案。

最后关联的表有可能不在同一数据库中,所以基本不可能进行联合查詢需要借助大数据技术来实现,也就是上面所说的第3种方法即通过大数据技术统一聚合和处理关系型数据库的数据,然后对外提供查詢操作请参考第5章的内容。

通过大数据方式来提供聚合查询的方式如图3-10所示

3. 跨库事务难以实现

要避免在一个事务中同时修改数据库db0和數据库db1中的表,因为操作起来很复杂对效率也会有一定的影响。请参考第三章的内容

4. 同组数据跨库问题

要尽量把同一组数据放到同一囼数据库服务器上,不但在某些场景下可以利用本地事务的强一致性还可以使这组数据自治。

以电商为例我们的应用有两个数据库db0和db1,分库分表后按照id维度,将卖家A的交易信息存放到db0中当数据库db1挂掉时,卖家A的交易信息不受影响依然可以正常使用。也就是说要避免数据库中的数据依赖另一数据库中的数据。

特别推荐一个分享架构+算法的优质内容还没关注的小伙伴,可以长按关注一下:
如有收獲点个在看,诚挚感谢

三(1)六1班有男生23人26人女生14人,每次抽一人做游戏抽到(  )的可能性大.

参考资料

 

随机推荐