最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MySQL同步ES的五種方案及對(duì)比詳解

 更新時(shí)間:2025年09月24日 08:32:06   作者:蘇三說(shuō)技術(shù)  
有些小伙伴在工作中可能遇到過(guò)數(shù)據(jù)庫(kù)查詢慢的問(wèn)題,特別是模糊查詢和復(fù)雜聚合查詢,這時(shí)候引入ES(Elasticsearch)作為搜索引擎是個(gè)不錯(cuò)的選擇,所以本文給大家介紹了MySQL同步ES的五種方案,需要的朋友可以參考下

前言

有些小伙伴在工作中可能遇到過(guò)數(shù)據(jù)庫(kù)查詢慢的問(wèn)題,特別是模糊查詢和復(fù)雜聚合查詢,這時(shí)候引入ES(Elasticsearch)作為搜索引擎是個(gè)不錯(cuò)的選擇。

今天我們來(lái)聊聊MySQL同步到ES(Elasticsearch)的5種常見(jiàn)方案。

希望對(duì)你會(huì)有所幫助。

一、為什么需要MySQL同步到ES?

在我們深入討論方案之前,先明確一下為什么需要將MySQL數(shù)據(jù)同步到ES:

  1. 全文搜索能力:ES提供強(qiáng)大的全文搜索功能,遠(yuǎn)超MySQL的LIKE查詢。
  2. 復(fù)雜聚合分析:ES支持復(fù)雜的聚合查詢,適合大數(shù)據(jù)分析。
  3. 高性能查詢:ES的倒排索引設(shè)計(jì)使查詢速度極快。
  4. 水平擴(kuò)展:ES天生支持分布式,易于水平擴(kuò)展。

先來(lái)看一下整體的同步架構(gòu)圖:

接下來(lái),我們?cè)敿?xì)分析每種方案的實(shí)現(xiàn)原理和優(yōu)缺點(diǎn)。

二、方案一:雙寫方案

雙寫方案是最直接的同步方式,即在業(yè)務(wù)代碼中同時(shí)向MySQL和ES寫入數(shù)據(jù)。

示例代碼:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private ElasticsearchTemplate elasticsearchTemplate;
    
    @Transactional
    public void addUser(User user) {
        // 寫入MySQL
        userMapper.insert(user);
        
        // 寫入Elasticsearch
        IndexQuery indexQuery = new IndexQueryBuilder()
            .withObject(user)
            .withId(user.getId().toString())
            .build();
        elasticsearchTemplate.index(indexQuery);
    }
    
    @Transactional
    public void updateUser(User user) {
        // 更新MySQL
        userMapper.updateById(user);
        
        // 更新Elasticsearch
        IndexRequest request = new IndexRequest("user_index")
            .id(user.getId().toString())
            .source(JSON.toJSONString(user), XContentType.JSON);
        elasticsearchTemplate.getClient().index(request, RequestOptions.DEFAULT);
    }
}

優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):

  • 實(shí)現(xiàn)簡(jiǎn)單,不需要引入額外組件
  • 實(shí)時(shí)性高,數(shù)據(jù)立即同步

缺點(diǎn):

  • 數(shù)據(jù)一致性難保證,需要處理分布式事務(wù)問(wèn)題
  • 代碼侵入性強(qiáng),業(yè)務(wù)邏輯復(fù)雜
  • 性能受影響,每次寫操作都要等待ES響應(yīng)

適用場(chǎng)景

適合數(shù)據(jù)量不大,對(duì)實(shí)時(shí)性要求高,且能夠接受一定數(shù)據(jù)不一致的業(yè)務(wù)場(chǎng)景。

三、方案二:定時(shí)任務(wù)方案

定時(shí)任務(wù)方案通過(guò)定期掃描MySQL數(shù)據(jù)變化來(lái)同步到ES。

示例代碼:

@Component
public class UserSyncTask {
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private UserESRepository userESRepository;
    
    // 每5分鐘執(zhí)行一次
    @Scheduled(fixedRate = 5 * 60 * 1000)
    public void syncUserToES() {
        // 查詢最近更新的數(shù)據(jù)
        Date lastSyncTime = getLastSyncTime();
        List<User> updatedUsers = userMapper.selectUpdatedAfter(lastSyncTime);
        
        // 同步到ES
        for (User user : updatedUsers) {
            userESRepository.save(user);
        }
        
        // 更新最后同步時(shí)間
        updateLastSyncTime(new Date());
    }
    
    // 獲取最后同步時(shí)間
    private Date getLastSyncTime() {
        // 從數(shù)據(jù)庫(kù)或Redis中獲取
        // ...
    }
}

數(shù)據(jù)更新追蹤策略

為了提高同步效率,通常需要設(shè)計(jì)良好的數(shù)據(jù)變更追蹤機(jī)制:

優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):

  • 實(shí)現(xiàn)簡(jiǎn)單,不需要修改現(xiàn)有業(yè)務(wù)代碼
  • 對(duì)數(shù)據(jù)庫(kù)壓力可控,可以調(diào)整同步頻率

缺點(diǎn):

  • 實(shí)時(shí)性差,數(shù)據(jù)同步有延遲
  • 可能遺漏數(shù)據(jù),如果系統(tǒng)崩潰會(huì)丟失部分?jǐn)?shù)據(jù)
  • 掃描全表可能對(duì)數(shù)據(jù)庫(kù)造成壓力

適用場(chǎng)景

適合對(duì)實(shí)時(shí)性要求不高,數(shù)據(jù)變更不頻繁的場(chǎng)景。

四、方案三:Binlog同步方案

Binlog是MySQL的二進(jìn)制日志,記錄了所有數(shù)據(jù)變更操作。

通過(guò)解析Binlog可以實(shí)現(xiàn)數(shù)據(jù)同步。

示例代碼:

public class BinlogSyncService {
    public void startSync() {
        BinaryLogClient client = new BinaryLogClient("localhost", 3306, "username", "password");
        
        client.registerEventListener(new BinaryLogClient.EventListener() {
            @Override
            public void onEvent(Event event) {
                EventData eventData = event.getData();
                
                if (eventData instanceof WriteRowsEventData) {
                    // 插入操作
                    WriteRowsEventData writeData = (WriteRowsEventData) eventData;
                    processInsertEvent(writeData);
                } elseif (eventData instanceof UpdateRowsEventData) {
                    // 更新操作
                    UpdateRowsEventData updateData = (UpdateRowsEventData) eventData;
                    processUpdateEvent(updateData);
                } elseif (eventData instanceof DeleteRowsEventData) {
                    // 刪除操作
                    DeleteRowsEventData deleteData = (DeleteRowsEventData) eventData;
                    processDeleteEvent(deleteData);
                }
            }
        });
        
        client.connect();
    }
    
    private void processInsertEvent(WriteRowsEventData eventData) {
        // 處理插入事件,同步到ES
        for (Serializable[] row : eventData.getRows()) {
            User user = convertRowToUser(row);
            syncToElasticsearch(user, "insert");
        }
    }
    
    private void syncToElasticsearch(User user, String operation) {
        // 同步到ES的實(shí)現(xiàn)
        // ...
    }
}

優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):

  • 實(shí)時(shí)性高,幾乎實(shí)時(shí)同步
  • 對(duì)業(yè)務(wù)代碼無(wú)侵入,不需要修改現(xiàn)有代碼
  • 性能好,不影響數(shù)據(jù)庫(kù)性能

缺點(diǎn):

  • 實(shí)現(xiàn)復(fù)雜,需要解析Binlog格式
  • 需要考慮Binlog格式變更的兼容性問(wèn)題
  • 主從切換時(shí)可能需要重新同步

適用場(chǎng)景

適合對(duì)實(shí)時(shí)性要求高,數(shù)據(jù)量大的場(chǎng)景。

五、方案四:Canal方案

Canal是阿里巴巴開(kāi)源的MySQL Binlog增量訂閱&消費(fèi)組件,簡(jiǎn)化了Binlog同步的復(fù)雜性。

示例代碼:

# canal.properties 配置
canal.instance.master.address=127.0.0.1:3306
canal.instance.dbUsername=username
canal.instance.dbPassword=password
canal.instance.connectionCharset=UTF-8
canal.instance.filter.regex=.*\..*
public class CanalClientExample {
    public static void main(String[] args) {
        // 創(chuàng)建Canal連接
        CanalConnector connector = CanalConnectors.newSingleConnector(
            new InetSocketAddress("127.0.0.1", 11111), "example", "", "");
        
        try {
            connector.connect();
            connector.subscribe(".*\..*");
            
            while (true) {
                Message message = connector.getWithoutAck(100);
                long batchId = message.getId();
                
                if (batchId != -1 && !message.getEntries().isEmpty()) {
                    processEntries(message.getEntries());
                    connector.ack(batchId); // 提交確認(rèn)
                }
                
                Thread.sleep(1000);
            }
        } finally {
            connector.disconnect();
        }
    }
    
    private static void processEntries(List<CanalEntry.Entry> entries) {
        for (CanalEntry.Entry entry : entries) {
            if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) {
                CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(entry.getStoreValue());
                
                for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
                    if (rowChange.getEventType() == CanalEntry.EventType.INSERT) {
                        processInsert(rowData);
                    } elseif (rowChange.getEventType() == CanalEntry.EventType.UPDATE) {
                        processUpdate(rowData);
                    } elseif (rowChange.getEventType() == CanalEntry.EventType.DELETE) {
                        processDelete(rowData);
                    }
                }
            }
        }
    }
}

架構(gòu)設(shè)計(jì)

Calan方案的架構(gòu)如下:

優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):

  • 實(shí)時(shí)性高,延遲低
  • 對(duì)業(yè)務(wù)系統(tǒng)無(wú)侵入
  • 阿里巴巴開(kāi)源項(xiàng)目,社區(qū)活躍

缺點(diǎn):

  • 需要部署維護(hù)Canal服務(wù)器
  • 需要處理網(wǎng)絡(luò)分區(qū)和故障恢復(fù)
  • 可能產(chǎn)生數(shù)據(jù)重復(fù)同步問(wèn)題

適用場(chǎng)景

適合大數(shù)據(jù)量、高實(shí)時(shí)性要求的場(chǎng)景,且有專門團(tuán)隊(duì)維護(hù)中間件。

六、方案五:MQ異步方案

MQ異步方案通過(guò)消息隊(duì)列解耦MySQL和ES的同步過(guò)程,提高系統(tǒng)的可靠性和擴(kuò)展性。

示例代碼:

@Service
public class UserService {
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    @Transactional
    public void addUser(User user) {
        // 寫入MySQL
        userMapper.insert(user);
        
        // 發(fā)送消息到MQ
        rabbitTemplate.convertAndSend("user.exchange", "user.add", user);
    }
    
    @Transactional
    public void updateUser(User user) {
        // 更新MySQL
        userMapper.updateById(user);
        
        // 發(fā)送消息到MQ
        rabbitTemplate.convertAndSend("user.exchange", "user.update", user);
    }
}

@Component
public class UserMQConsumer {
    @Autowired
    private UserESRepository userESRepository;
    
    @RabbitListener(queues = "user.queue")
    public void processUserAdd(User user) {
        userESRepository.save(user);
    }
    
    @RabbitListener(queues = "user.queue")
    public void processUserUpdate(User user) {
        userESRepository.save(user);
    }
    
    @RabbitListener(queues = "user.queue")
    public void processUserDelete(Long userId) {
        userESRepository.deleteById(userId);
    }
}

消息隊(duì)列選型對(duì)比

不同的消息隊(duì)列產(chǎn)品有不同特點(diǎn),下面是常見(jiàn)MQ的對(duì)比:

優(yōu)缺點(diǎn)分析

優(yōu)點(diǎn):

  • 完全解耦,MySQL和ES同步過(guò)程相互獨(dú)立
  • 高可用,MQ本身提供消息持久化和重試機(jī)制
  • 可擴(kuò)展,可以方便地增加消費(fèi)者處理消息

缺點(diǎn):

  • 系統(tǒng)復(fù)雜度增加,需要維護(hù)MQ集群
  • 可能產(chǎn)生消息順序問(wèn)題,需要處理消息順序性
  • 數(shù)據(jù)一致性延遲,依賴于消息消費(fèi)速度

適用場(chǎng)景

適合大型分布式系統(tǒng),對(duì)可靠性和擴(kuò)展性要求高的場(chǎng)景。

七、5種方案對(duì)比

為了更直觀地比較這5種方案,我們來(lái)看一個(gè)綜合對(duì)比表格:

方案名稱實(shí)時(shí)性數(shù)據(jù)一致性系統(tǒng)復(fù)雜度性能影響適用場(chǎng)景
雙寫方案難保證小規(guī)模應(yīng)用
定時(shí)任務(wù)最終一致非實(shí)時(shí)場(chǎng)景
Binlog方案最終一致大數(shù)據(jù)量高實(shí)時(shí)
Canal方案最終一致大數(shù)據(jù)量高實(shí)時(shí)
MQ異步方案最終一致分布式大型系統(tǒng)

選擇建議

有些小伙伴在工作中可能會(huì)糾結(jié)選擇哪種方案,這里給出一些建議:

  1. 初創(chuàng)項(xiàng)目或小規(guī)模系統(tǒng):可以選擇雙寫方案或定時(shí)任務(wù)方案,實(shí)現(xiàn)簡(jiǎn)單。
  2. 中大型系統(tǒng):建議使用Canal方案或MQ異步方案,保證系統(tǒng)的可靠性和擴(kuò)展性。
  3. 大數(shù)據(jù)量高實(shí)時(shí)要求:Binlog方案或Canal方案是最佳選擇。
  4. 已有MQ基礎(chǔ)設(shè)施:優(yōu)先考慮MQ異步方案,充分利用現(xiàn)有資源。

注意事項(xiàng)

無(wú)論選擇哪種方案,都需要注意以下幾點(diǎn):

  1. 冪等性處理:同步過(guò)程需要保證冪等性,防止重復(fù)數(shù)據(jù)。
  2. 監(jiān)控告警:建立完善的監(jiān)控體系,及時(shí)發(fā)現(xiàn)同步延遲或失敗。
  3. 數(shù)據(jù)校驗(yàn):定期校驗(yàn)MySQL和ES中的數(shù)據(jù)一致性。
  4. 容錯(cuò)機(jī)制:設(shè)計(jì)良好的故障恢復(fù)機(jī)制,避免數(shù)據(jù)丟失。

總結(jié)

MySQL同步到ES(Elasticsearch)是現(xiàn)代應(yīng)用開(kāi)發(fā)中常見(jiàn)的需求,選擇合適的同步方案對(duì)系統(tǒng)性能和可靠性至關(guān)重要。

本文介紹了5種常見(jiàn)方案,各有優(yōu)缺點(diǎn),適用于不同場(chǎng)景。

在實(shí)際項(xiàng)目中,可能需要根據(jù)具體需求組合使用多種方案,或者對(duì)某種方案進(jìn)行定制化改造。

重要的是要理解每種方案的原理和特點(diǎn),才能做出合理的技術(shù)選型。

以上就是MySQL同步ES的五種方案及對(duì)比詳解的詳細(xì)內(nèi)容,更多關(guān)于MySQL同步ES方案的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MySQL 表空間碎片的概念及相關(guān)問(wèn)題解決

    MySQL 表空間碎片的概念及相關(guān)問(wèn)題解決

    這篇文章主要介紹了MySQL 表空間碎片的概念及相關(guān)問(wèn)題解決,幫助大家更好的理解和學(xué)習(xí)使用MySQL,感興趣的朋友可以了解下
    2021-05-05
  • Mysql開(kāi)啟外網(wǎng)訪問(wèn)的全過(guò)程記錄

    Mysql開(kāi)啟外網(wǎng)訪問(wèn)的全過(guò)程記錄

    mysql 默認(rèn)是不允許外放訪問(wèn)的,只允許 localhost 或 127.0.0.1 訪問(wèn),下面這篇文章主要給大家介紹了關(guān)于Mysql開(kāi)啟外網(wǎng)訪問(wèn)的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-05-05
  • mysql8新特性之binlog_expire_logs_seconds淺析

    mysql8新特性之binlog_expire_logs_seconds淺析

    MySQL8中新增了不少新特性,這些特性提高了數(shù)據(jù)庫(kù)的安全性和性能,使數(shù)據(jù)庫(kù)管理員能夠更靈活地進(jìn)行賬戶管理工作,下面這篇文章主要給大家介紹了關(guān)于mysql8新特性之binlog_expire_logs_seconds的相關(guān)資料,需要的朋友可以參考下
    2023-02-02
  • MySQL如何匹配字符串函數(shù)

    MySQL如何匹配字符串函數(shù)

    MySQL提供多個(gè)字符串匹配函數(shù),如like、locate、position、instr和find_in_set,其中l(wèi)ocate、position、instr和find_in_set均返回字符在字段中的索引(如果包含),否則返回0,特別地,find_in_set適用于字段為數(shù)組的情況
    2024-11-11
  • Centos7 下Mysql5.7.19安裝教程詳解

    Centos7 下Mysql5.7.19安裝教程詳解

    這篇文章主要介紹了Centos7 下Mysql5.7.19安裝教程詳解,小編認(rèn)為非常不錯(cuò),特此分享到腳本之家平臺(tái),需要的朋友參考下吧
    2017-09-09
  • MySQL日期格式化yyyy-mm-dd詳解(DATE_FORMAT()函數(shù))

    MySQL日期格式化yyyy-mm-dd詳解(DATE_FORMAT()函數(shù))

    MySQL提供了很多功能強(qiáng)大、方便易用的函數(shù),在進(jìn)行數(shù)據(jù)庫(kù)管理以及數(shù)據(jù)的查詢和操作時(shí),幫助我們提高對(duì)數(shù)據(jù)庫(kù)的管理效率,下面這篇文章主要給大家介紹了關(guān)于MySQL日期格式化yyyy-mm-dd(DATE_FORMAT()函數(shù))的相關(guān)資料,需要的朋友可以參考下
    2023-01-01
  • MySQL存儲(chǔ)過(guò)程的創(chuàng)建和使用示例詳解

    MySQL存儲(chǔ)過(guò)程的創(chuàng)建和使用示例詳解

    文章介紹了MySQL存儲(chǔ)過(guò)程的概念、創(chuàng)建與刪除、調(diào)用、變量使用、參數(shù)、流程控制、管理和案例,存儲(chǔ)過(guò)程可以封裝SQL指令,提高執(zhí)行效率,但也有一定局限性,感興趣的朋友跟隨小編一起看看吧
    2025-02-02
  • MySQL中TINYINT、INT 和 BIGINT的具體使用

    MySQL中TINYINT、INT 和 BIGINT的具體使用

    MySQL提供了多種整數(shù)類型來(lái)滿足不同的數(shù)據(jù)存儲(chǔ)需求,本文主要介紹了MySQL中TINYINT、INT 和 BIGINT的具體使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-07-07
  • MySql存儲(chǔ)過(guò)程學(xué)習(xí)知識(shí)小結(jié)

    MySql存儲(chǔ)過(guò)程學(xué)習(xí)知識(shí)小結(jié)

    這篇文章主要介紹了MySql存儲(chǔ)過(guò)程學(xué)習(xí)知識(shí)小結(jié)的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-06-06
  • MySQL范圍查詢優(yōu)化的場(chǎng)景實(shí)例詳解

    MySQL范圍查詢優(yōu)化的場(chǎng)景實(shí)例詳解

    范圍訪問(wèn)方法使用單一索引去檢索表中的數(shù)據(jù)包含一個(gè)或者多個(gè)索引值的行記錄,下面這篇文章主要給大家介紹了關(guān)于MySQL范圍查詢優(yōu)化的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06

最新評(píng)論

宜兴市| 阿图什市| 黄浦区| 临西县| 塔城市| 丰县| 英吉沙县| 郸城县| 十堰市| 宜阳县| 泰和县| 永川市| 邹平县| 孟连| 交口县| 若羌县| 河池市| 天祝| 霸州市| 安康市| 中阳县| 辛集市| 阿拉善右旗| 新密市| 宁远县| 瑞昌市| 德州市| 赫章县| 绵竹市| 塔河县| 刚察县| 镇宁| 永济市| 竹溪县| 南投县| 日土县| 华宁县| 安阳市| 巴青县| 运城市| 台前县|