冷热分离是一个性价比高的方案,但不是灵丹妙药。还有很多局限性,比如:查询冷数据慢,业务不能修改冷数据,冷数据太多,在一定程度上,系统还是应付不了。如果此时需要解决以上问题,可以采用另一种方案:使用查询分离来优化大业务主表数据查询慢的问题。什么是查询分离?查询分离从字面上理解起来非常容易。其实就是写数据的时候把一个备份的数据保存到另一个存储系统,查询的时候直接从另一个存储系统获取数据,如下图:查询分离以上只是一个简单的架构图,一些细节还在需要研究的是:什么时候会触发查询分离?如何实现查询分离?查询数据存储系统选型?如何使用查询数据?查询分离的适用场景有哪些?在实际业务中遇到以下几种情况时,可以考虑使用查询分离方案。数据量大;所有写数据请求的效率都可以接受;查询数据请求效率很低;所有数据都可能随时被修改;业务要我们优化查询数据的功能。我优化了SaaS客服系统的架构。系统有工单查询功能。工单表中存储着千万条数据,查询工单表数据时需要关联十几个子表。每个子表的数据也是过亿。面对如此海量的数据,就像之前的冷热分离一样,客户每次查询数据都要几十秒才能返回结果。即使我们使用索引、SQL等数据库优化技术,效果仍然不明显。工单表中的一些数据是几年前的。客户表示,这些数据与诉讼问题有关,需要不断更新。所以,我们不能把这些旧数据存储在其他地方,也不能使用之前的冷热分离方案。解决。最终我们采用了查询分离的方案顺利解决了这个问题:更新的数据放在一个数据库中,查询的数据放在另一个系统中。因为数据更新都是单表更新,不需要关联,也不需要外键,更新速度立马提升。客户每次查询数据,可在500ms内得到返回结果。什么时候触发查询分离?简单的说就是什么时候把一条数据保存到查询数据库中。其实就是数据异构的过程。详细文章可以参考我之前的文章:数据异构应该怎么做。yyds~这里分三种方法如下:同步和异步创建binlog。1、同步创建和修改业务代码:写入常规数据后,同步创建查询数据。这种方案的优缺点也非常明显:优点:保证了查询数据的一致性和实时性缺点:业务代码入侵性比较强;拖慢写操作的效率2.业务代码的异步建立和修改:写入数据后,异步建立这种查询数据的方案优缺点如下:优点:不影响主流程缺点:有a数据一致性的问题3.binlog方式也是业界常用的解决方案。创建查询数据的方式如下:这种方案的优缺点如下:优点:不影响主进程;代码入侵为0缺点:数据一致性有问题;架构相对复杂。如何实现查询分离?以上三种方案都是比较常见的方案,第一种同步方式比较简单。本文介绍异步方法。异步方式有很多,可以在内存中操作,但是有一些缺点:数据太多,内存有限,服务重启,内存数据会丢失。所以最后我们可以选择MQ的方式,那么这时候就涉及到MQ的技术选型了,这里有两个建议:如果你的公司已经使用了MQ,那就继续使用如果公司目前没有引入MQ,架构团队需要考虑选型对于MQ的选型,可以看我之前的文章:浅谈MQ技术选型。当然,一旦引入MQ,需要考虑的问题很多,如下:1、MQ突然宕机了怎么办?MQ宕机意味着查询数据无法继续创建。我们可以在写入数据的同时给数据加上一个标志字段(transferred,untransferred)。MQ启动时,查询所有未传输的数据,继续构建查询数据的解决方案有很多种。根据实际业务情况考虑。2、消息的幂等消费必须保证消息的幂等消费,避免重复创建数据。比如主数据的订单A更新后,我们插入A,但是此时系统出了问题,系统误认为查询数据没有更新,重新插入更新订单A.3.消息的时间。比如一个订单A更新了一次数据到A1,线程A就把A1的数据移动到查询数据中。过了一会,后台订单A再次更新了数据,变成了A2,线程B也开始工作,将A2的数据移动到查询数据中。所谓时序就是如果线程A比线程B早启动,但是数据处理动作比线程B晚完成,那么查询数据有没有可能最终变成过期A1查询数据的存储系统选择?既然要解决表数据量大查询慢的问题,用关系型数据库是肯定不行的,那么有没有其他的选择呢?内存数据库虽然性能很高,比如Redis,但是不适合海量数据,而且太贵了。那么比较适合的有以下三种:MongoDBHBaseElasticsearch。你可以直接使用它;另一种是选择你熟悉的东西。比如我们在设计架构方案的时候,为什么选择Elasticsearch?除了ES对查询的可扩展性支持,最重要的一点是我们团队对Elasticsearch非常熟悉。如何使用查询数据?查询数据非常简单。每个数据库都有相应的API,可以直接调用查询。但是,这里有个问题:数据查询更新前,查询数据不一致怎么办?,给出了两种解决方案:直到查询数据更新到最新,才允许用户查询。(我们没有用过这种设计,但是我在市面上看到过这样的设计。)用户提示:您当前查询的数据可能是1秒前的数据。如果发现数据不准确,可以尝试刷新,这种提示一般更容易让用户接受。小结本文介绍了一种大表数据查询慢的解决方案:查询分离,但这不是灵丹妙药。还有一些缺点,比如表数据量大,写入慢?这篇文章后面再介绍吧!
