企業級搜索系統案例源碼(已經非常精簡),根據前公司項目搭建,基於 spring-boot + elasticsearch + canal

技術選型:spring-boot + elasticsearch + canal
GitHub地址:https://github.com/HappyWjl/es-home.git
如果該項目對您有幫助,您可以點右上角 “Star” 支持一下 謝謝!
或者您可以 “follow” 一下,該項目將持續更新,不斷完善功能。
轉載還請註明出處,謝謝了
博主QQ:820155406

一、準備工作:

  • IDEA:

  • JDK1.8:

  • mysql數據庫:

安裝完mysql數據庫後,把bin_log設置打開,如果不確定是否已經打開,可執行 show variables like ‘log_bin%’;
如果顯示如下,那說明已經開啓bin_log日誌,如果沒有,如果想使用canal進行數據同步,自行百度開啓bin_log
這是個人數據庫截圖,用於演示bin_log是否開啓

接下來,新建數據庫:db_search 並運行準備好的sql文件 db_search.sql (項目源碼中包含這個sql文件,可自行下載)
執行完sql後,數據庫中數據應該是這樣的:
數據庫數據

  • elasticsearch安裝:https://blog.csdn.net/u012888052/article/details/79710429

  • elasticsearch-head插件安裝 :https://blog.csdn.net/u012888052/article/details/79710429

  • elasticsearch分詞器插件安裝 :https://blog.csdn.net/u012888052/article/details/81941912

如果不需要進行字段的分詞查詢,可不安裝分詞器,但是絕大多數業務場景,都是需要分詞查詢的,並且目前Demo中有分詞代碼,建議安裝。

  • canal服務端安裝,官方下載地址:https://github.com/alibaba/canal/releases
  •   附:canal Api地址:https://www.bookstack.cn/read/canal/1.md
    
  •   canal 官方GitHub:https://github.com/alibaba/canal
    

打開鏈接,下載第一個壓縮包,然後解壓,解壓後應該是這個樣子的:
canal服務端文件夾
bin爲啓動文件夾
conf爲配置文件夾
lib爲相關jar包文件夾
logs爲日誌文件夾
前面我們已經安裝好Mysql數據庫,並且已經建好了一個測試數據庫,那麼我們接下來進行 Mysql + canal 服務端的配置
打開canal的conf文件夾,在裏面新建 articlesubscibe 文件夾,再在 articlesubscibe 文件夾中,複製conf文件夾下example中的instance.properties 文件並修改配置,如下圖(配置是我本機的配置,可根據實際需要改成自己的):
canal配置數據庫
接下來,找到 canal.properties 配置文件進行編輯,找到 canal.destinations 配置參數,進行文件夾掃描配置,如下圖:
canal配置文件圖解
文件夾名稱可自行定義,與上一步新建的文件夾名稱相同即可。然後將conf文件夾下自帶的 example 文件夾刪除,爲什麼要刪除呢?因爲實際開發中需要同步的數據庫、數據表是很多的,自帶的文件夾是個案例,用於第一次配置時copy,後面我們應該根據實際需要,新建多個文件夾,區分不同的業務監聽,便於後續維護。
至此,conf文件夾應該是這個樣子:
canal中conf文件夾

  • git安裝(用於代碼管理,主要是爲下一步下載Demo做準備):略

  • 項目源程序Demo(已經是最精簡的例子了,單表同步,單表查詢)GitHub地址(喜歡的朋友幫忙點個star):https://github.com/HappyWjl/es-home.git

以上,就是項目的準備工作,接下來就着重講解項目結構,以及數據是如何同步、如何查詢的乾貨。


二、項目結構:

  • 具體描述項目前,我經常想到大象裝冰箱的步驟:

  • 打開冰箱門、將大象放進去、關上冰箱門

  • 現在做這個項目,也分爲三個步驟:

  • 同步實時數據(data-dump)、同步歷史數據(data-migration)、按條件查詢es數據(data-search)

  • 同步實時數據:
    當數據庫中 新增/刪除/更新 一條數據時,需要實時同步到es
    注意!這裏進行實時同步時,需要避免監聽表的批量修改數據,不然會造成數據積壓,一時間同步不過來。
    如果必須要批量修改Mysql表數據時,應先把canal服務端停掉

  • 同步歷史數據:
    當數據庫中已經有舊的數據,且數據量很多,es中沒有時,需要將歷史數據批量灌入到es
    如果沒有歷史數據,需要同步到es,就不需要這一步了

  • 按條件查詢es數據:
    前兩步能夠保證es中的數據完整性,只能算前提條件,這一步是最出活的,做完這一步,能夠查詢出想要的,就算完成

利用git下載完項目後,就可以進行項目部署了,將項目導入到IDEA中,可以看到es-home主項目,下圖是項目主要結構:
es-home項目主結構

項目採用的相關技術:spring-boot、mybatis、maven、elasticsearch、canal

具體可查看詳細腦圖:
es-home腦圖1
es-home腦圖2
es-home腦圖3


data-dump模塊:

  • 這個項目主要的功能是實時同步數據,其中包含了canal客戶端代碼,用於接收canal服務端傳來的數據庫數據

  • 首先啓動 DataDumpApplication.java ,可以看到啓動文件會加載數據源、掃描spring下的配置文件、指定啓動順序(@Order註解)、執行run方法,建立es鏈接
    DataDumpApplication.java文件截圖

  • 在啓動完後,ElasticsearchEnvInitRunner.java文件會接下來運行,因爲實現了CommandLineRunner,並且有@Order(2)註解
    這裏會進行索引檢查,如果es中沒有代碼中的索引,會新建一個索引名稱
    ElasticsearchEnvInitRunner.java文件

  • 在新建索引過程中,可以對新建的索引進行設置,例如:設置字段分詞、設置字段經緯度,用於距離排序
    設置初始索引

  • 接下來,CanalClientRunner.java文件會繼續執行,因爲實現了CommandLineRunner
    這個文件會和canal服務端建立鏈接
    CanalClientRunner.java文件

注:在使用SpringBoot構建項目時,我們通常有一些預先數據的加載。那麼SpringBoot提供了一個簡單的方式來實現–CommandLineRunner。
CommandLineRunner是一個接口,我們需要時,只需實現該接口就行。如果存在多個加載的數據,我們也可以使用@Order註解來排序。

  • 當canal服務端接收到mysql傳過來的bin_log日誌,會通過和客戶端的鏈接,傳到客戶端 AbstractCanalCoreManager.java 類,客戶端可根據設置批量讀取傳過來的數據,取決於業務數據的變動速度,以及canal客戶端同步到es中的消費速度
    canal處理數據1

  • 消費過程中,由於真正企業中的數據量變動比較大,所以採用多線程的方式去消費數據
    canal處理數據2

  • 接下來,通過 entry.getEntryType() 可進行數據庫事物判斷,並分別對數據進行處理,再通過多線程依次處理這些數據
    canal處理數據3

  • 分別判斷每條數據是 增/刪/改 哪種類型,分別進行處理。當是刪除時,進行es刪除操作;當是 增/改 時,進行es增改操作
    canal處理數據4

  • 在向es中修改數據前,調用了analysisColumn(rowData.getBeforeColumnsList()); 方法,這是對數據庫特殊字段的處理,因爲es接收數據的類型和Mysql不完全一致,所以需要將特殊字段處理下,目前已知的特殊字段有:timestamp、datetime、date、time、blob 真的是萬惡的時間,費我青春,害我敲碼!
    處理數據庫特殊字段

注:時間類型存儲到es中會自動有時區轉換,例如傳入時間是2018-08-21 18:00:00 es中會存儲成 2018-08-21 10:00:00 中間會差8小時,所以需要在查詢數據時,進行時間差的轉換

  • 刪除操作,調用的是封裝的刪除方法
    es刪除方法封裝

  • getDateMap()方法,是在對es進行操作的最後一步之前,可對特殊數據進行處理,根據實際的需求來,簡單的需求或者優質的表結構,不需要這一步,經過封裝好的es新增/更新方法,就可以到es了
    es特殊索引數據處理

  • 新增/修改操作,調用的是封裝的方法
    es新增/更新 方法封裝


data-migration模塊:

  • 這個項目主要的功能是同步歷史數據,當數據庫中已經有舊的數據,且數據量很多,es中沒有時,需要將歷史數據批量灌入到es。如果沒有歷史數據,需要同步到es,就不需要這一步了

  • 這個項目和data-dump項目有相當一部分相同的代碼,下面講到的話就簡單略過

  • 首先啓動 DataMigrationApplication.java ,可以看到啓動文件會掃描spring下的配置文件
    DataMigrationApplication啓動

  • spring下的配置文件被掃描,mybatis相關配置也會被加載,此處省略,這裏不是重點。。。

  • 在啓動完後,ElasticSearchInitRunner.java文件會接下來運行,因爲實現了CommandLineRunner
    這裏會進行es連接池檢查

  • 在啓動完後,可以看到項目啓動端口爲:8082
    data-migration 模塊啓動

  • 接下來在瀏覽器中請求url:http://localhost:8082/api/article/checkindex
    可以進行索引檢查,如果沒有這個索引,會新建索引,這裏同上面data-dump一樣,索引可以設置分詞等屬性

  • 然後請求url:http://localhost:8082/api/article/articletoes
    就可以進行數據批量同步,接下來我簡單講下歷史數據批量同步的步驟

  • 請求接口經過網絡中的層層傳遞,一直訪問到ArticleController.java
    進行url請求

  • 然後通過 articleSyncToEsManager.syncDataControl(); 同步數據到ES主控方法
    這個方法,首先通過mybatis批量查詢出要同步錶的歷史數據,再進行循環,逐條處理數據
    es主同步方法

  • 當看到 getDateMap()時,如果上面data-dump模塊的結構看的夠仔細,那就能接上了,後面是完全一樣的數據處理,接下來的介紹省略~可以參考上面寫到的getDateMap()續讀


data-search模塊:

  • 這個模塊是進行數據的查詢,在做這一步前,請確保es中已經有相關數據,不然程序寫對了,也查不出來的,這時es應該可以看到初始數據如下圖:
    es數據展示圖

  • 首先啓動 DataSearchApplication.java ,可以看到啓動文件會掃描spring下的配置文件
    DataSearchApplication啓動

  • 在啓動完後,可以看到項目啓動端口爲:8083
    data-search模塊啓動

  • 接下來在postman中請求url(也可以用其他接口請求工具,注意是post請求):http://localhost:8083/api/article/getArticleList
    postman請求url

  • 可以看到請求返回結果已經查詢到了結果

  • 請求接口經過網絡中的層層傳遞,一直訪問到ArticleController.java
    ArticleController被請求

  • 再經過service實現層,進行es查詢,由於es查詢後返回結果被封裝成String,所以還需要轉成Object才方便處理數據,再返回
    service.impl進行es查詢

  • 由於這個模塊主要實現的是查詢功能,那麼具體的查詢需要仔細講一下了,serviceImpl進行查詢時,調用了 articleSearchManager.queryArticleList(queryArticleSearchVO);

  • 進行查詢時,首先通過 elasticSearchInitClientManager.getElasticClient(); 獲取es連接

  • 再設置索引、設置查詢文章類型、組裝查詢條件

  • 查詢出來時,是es的數據類型 SearchResponse ,然後通過方法轉換成了Map

  • 但是這裏有一點需要注意,存數據到es中時,時間類型是有轉換的,現在是查詢出來,es中存儲的經轉換的類型是字符串,需要轉換成Data類型,並且可以留意下有沒有時差,之前提到過的時差如果出現了,這裏也可以進行數據修正

  • 再經過最後數據的組裝,轉成通用型的JSON字符串,返回
    es查詢邏輯1

  • 組裝邏輯應該根據實際情況封裝
    組裝查詢邏輯1
    組裝查詢邏輯2

暫時寫到這裏吧,項目整體就是這個樣子,實際使用中會比這個業務場景更復雜,這個Demo還是比較接近實際應用場景的,當然很多高級用法我沒有加在裏面,Demo複雜了就更難上手es了。

關於更多的查詢業務,可自行探索,我也在慢慢探索中,加油。

有什麼問題可以加QQ問,或者留言,看到就回。

作者:Happy王子樂
QQ:820155406

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章