读写分离
当一个公司业务不断扩展, 用户量大量增加, 原来使用的数据库很可能就撑不住了那么可以
Scale-in, 扩充硬件的性能, 但是很可能用户量继续增长, 增加的性能很快就吃光了
读写分离: 数据库撑不住了, 无非就是读写量过大, 特别是有一些复杂的查询比如最近 24 小时最热门的产品等需要很复杂的 SQL 语句, 运行起来当然是慢
但是为了读写分离, 需要把数据库拆分为 master 库和 Slave 库,
市面上主要的关系数据库都支持数据复制功能, 所以可以把一个数据库拆分为 Master 和 Slave 两种角色, 写操作在主上, 由 Master 服务器向其他 Slave 服务器进行同步
而读操作以及数据分析等离线操作都在 Slave 服务器上进行
我们知道互联网的很多应用都是读的, 这样有多个 Slave 可以负载分担一下, 又可以保证数据的可用性和正确性
但是相应的原有的应用代码也需要修改, 必须改为写数据用 master 库, 读数据的时候使用 slave 库, 就相当于重写了
复杂查询
但是就算重写了代码, 发现性能还是无法得到明显的提升, 原因仍然是使用了太多复杂的查询, 比如说有很多表在联接, 在数据库(四), 数据库组成部分里面我们都说过, 联接非常消耗性能
那么我们可不可以单独用一张表来存放过去 24 小时的热门产品啊, 这样只需要使用简单的 SQL 就能搞定
也就是说, 一套单一的数据库表对报表搜索事务等不同的行为是不适当的
现在的表是为了新增修改数据而设计的, 对复杂查询不适合
但是我们还需要考虑这个查询库如何更新的问题, 还就是可能不是实时更新, 我们能否忍受这种延迟的问题
CQRS
能否忍受延迟的问题需要从业务上来看, 比如过去 24 小时热门的极品, 一点点过时的信息没有太大的影响, 只要求最终一致即可
我们可以使用 CQRS(Command Query Responsibility Segregation), 也就是增删改的命令与查询责任分离
在 CQRS 中, 强调的是读 (Query) 写(Command)分离, 因为用户读到的数据通常是过时的, 那么为什么还需要从数据库读一遍呢, 可以直接建立一个读数据源可以是 Cache, 可以是 XMLJSON 等
那之前提到的怎么更新的问题怎么解决? 可以使用 Event, 也就是事件, 比如某个产品卖出去了, 可以发布一个事件, 修改原有的 Read Model
这样就通过事件机制把同步变成了异步
最后, 这种方法最好只在复杂查询中用, 原来的简单查询依然在关系型数据库里面取为什么呢? 因为引入一种新的技术需要付出代价, 比如同步变异步了, 还需要事件机制, 我们不能只看到新技术的优点, 而看不到缺点了
主要参考
从读写分离到 CQRS, 张大胖是如何解决性能问题的?
来源: http://www.bubuko.com/infodetail-2498858.html