文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

使用查询分离后,从20s优化到500ms,牛哇!

2024-11-29 19:32

关注

所以啊,咱们就得想办法给这个“胖子”减减肥,这就是查询分离的思路啦。咱们在写数据的时候,顺便把数据发到一个消息队列(MQ)里,然后异步地写到Elasticsearch(ES)里去。这样,查询的时候就不去主表凑热闹了,直接去ES里查,那速度可就快多了。

那具体怎么实现呢?咱们来看看代码。假设咱们用的是Java,首先,咱们得在写数据库的时候,把数据也发到MQ里去。这里咱们用RabbitMQ作为例子:

import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.Channel;


public class MessageSender {
    private final static String QUEUE_NAME = "data_queue";


    public void send(String message) throws Exception {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost("localhost");
        try (Connection connection = factory.newConnection();
             Channel channel = connection.createChannel()) {
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
            System.out.println(" [x] Sent '" + message + "'");
        }
    }
}

这段代码就是往MQ里发消息的。咱们在写数据库的时候,调用这个send方法,把数据作为消息发出去。

然后,咱们得有个消费者来监听这个MQ,把消息异步地写到ES里去。这里咱们用Elasticsearch的Java客户端来操作ES:

import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.CreateIndexResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.xcontent.XContentType;


public class EsDataWriter {
    private RestHighLevelClient client;


    public EsDataWriter(RestHighLevelClient client) {
        this.client = client;
    }


    public void writeToEs(String indexName, String jsonData) throws Exception {
        IndexRequest indexRequest = new IndexRequest(indexName);
        indexRequest.source(jsonData, XContentType.JSON);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        System.out.println("Data written to ES with id: " + indexResponse.getId());
    }
}

这段代码就是往ES里写数据的。咱们在MQ的消费者里,拿到消息后,调用这个writeToEs方法,把数据写到ES里去。那这样,查询的时候咱们就不去主表查了,直接去ES里查。那速度,嗖嗖的,500毫秒就出结果了。

但是啊,这里有个问题,就是数据还没同步到ES的时候,立马去查,查不到怎么办?这个嘛,咱们也有办法。咱们可以在数据库里加个字段,比如叫es_synced,表示数据是否已经同步到ES了。ES消费者写入ES后可以更新一下这个字段,查询单条数据的时候,咱们先查这个字段,如果已经同步了,就直接去ES里查;如果还没同步,就等一会儿再查,或者从主表里查。

如果是批量查多条数据那就不用做这个处理了,只允许查出来已经同步到ES的数据就可以了!

那历史数据怎么迁移呢?这个其实也不难。咱们可以写个脚本,把主表里的数据分批查出来,然后发到MQ里去,让消费者异步地写到ES里去。这样,历史数据也就迁移到ES里了。

总的来说啊,这个查询分离的思路还是挺实用的。它就像是一个减肥的方法,让咱们的“胖子”数据库跑得快了起来。当然啦,这个方法也不是万能的,比如如果数据量实在太大了,写入速度也会受影响。但是啊,对于大部分场景来说,这个方法还是挺好用的。

好啦,今天咱们就聊到这里啦。如果你也有类似的困扰,不妨试试这个方法~

来源:石杉的架构笔记内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯