起步侣背,實(shí)戰(zhàn)百萬(wàn)級(jí)商品數(shù)據(jù)實(shí)時(shí)同步搜索系統(tǒng)

百萬(wàn)級(jí)商品數(shù)據(jù)實(shí)時(shí)同步搜索系統(tǒng)主要面臨以下幾個(gè)難題:
  • 商家數(shù)據(jù)庫(kù)和商品數(shù)據(jù)庫(kù)是多臺(tái)不同的服務(wù)器,并且數(shù)據(jù)量達(dá)百萬(wàn)級(jí)慨默,如何才能實(shí)現(xiàn)跨數(shù)據(jù)庫(kù)的數(shù)據(jù)同步呢贩耐?

  • 商家和商品的數(shù)據(jù)是有從屬關(guān)系的,不然就會(huì)把肯德基的香辣雞腿堡掛到麥當(dāng)勞去厦取,這就尷尬了潮太!

  • 商家商品數(shù)據(jù)是經(jīng)常更新的,比如修改價(jià)格虾攻、庫(kù)存铡买、上下架等,那搜索服務(wù)可不能搜出一堆過(guò)時(shí)的數(shù)據(jù)霎箍,如果客戶(hù)明明搜出來(lái)的商品奇钞,點(diǎn)進(jìn)去后卻已下架了,那么客戶(hù)就要吐槽了漂坏!如何實(shí)現(xiàn)搜索數(shù)據(jù)與源數(shù)據(jù)庫(kù)增刪改均實(shí)時(shí)同步呢景埃?

帶著以上三個(gè)問(wèn)題,我們開(kāi)始了搜索服務(wù)的整體架構(gòu)設(shè)計(jì)顶别。

系統(tǒng)架構(gòu)設(shè)計(jì)思路

為了設(shè)計(jì)出合適的系統(tǒng)架構(gòu)谷徙,我們分析了現(xiàn)狀:

首先,商家數(shù)據(jù)和商品數(shù)據(jù)分別存儲(chǔ)在 2 個(gè)獨(dú)立的 MySQL8 數(shù)據(jù)庫(kù)驯绎,為滿(mǎn)足商家數(shù)據(jù)和商品數(shù)據(jù)的關(guān)聯(lián)完慧,我們需要將兩個(gè)庫(kù)中所需要的表實(shí)時(shí) ETL 到我們的搜索系統(tǒng)數(shù)據(jù)庫(kù)。

其次剩失,數(shù)據(jù)從商家屈尼、商品數(shù)據(jù)庫(kù) ETL 到搜索系統(tǒng)數(shù)據(jù)庫(kù)后,需要實(shí)時(shí)的組合成為商家關(guān)聯(lián)商品數(shù)據(jù)結(jié)構(gòu)赴叹,并以父子文檔的格式鸿染,存儲(chǔ)到 ES 中。

最后乞巧,商家涨椒、商品數(shù)據(jù)庫(kù)的增刪改操作,需要實(shí)時(shí)的同步到 ES 中,也就是 ES 中的數(shù)據(jù)蚕冬,需要支持實(shí)時(shí)的增加免猾、刪除和修改。

為此囤热,我們?cè)O(shè)計(jì)了 2 個(gè) Canal 組件猎提,第一個(gè) Canal 實(shí)現(xiàn)數(shù)據(jù) ETL,把商家旁蔼、商品數(shù)據(jù)庫(kù)的某些表及字段锨苏,抽取到搜索服務(wù)數(shù)據(jù)庫(kù)。

再利用第二個(gè) Canal棺聊,讀取搜索服務(wù) MySQL 數(shù)據(jù)庫(kù)的 Binlog伞租,實(shí)時(shí)傳輸?shù)?Kafka 消息隊(duì)列,再由 canal adapter 對(duì)數(shù)據(jù)進(jìn)行關(guān)聯(lián)限佩、父子文檔映射等葵诈,將處理好的數(shù)據(jù)存儲(chǔ)到 ElasticSearch 中。

具體系統(tǒng)架構(gòu)設(shè)計(jì)如下圖所示:
image

商家商品搜索系統(tǒng)架構(gòu)設(shè)計(jì)

項(xiàng)目實(shí)戰(zhàn)

環(huán)境及軟件說(shuō)明

操作系統(tǒng):CentOS 7
canal:canal.adapter-1.1.4祟同,canal.deployer-1.1.4
kafka:kafka_2.12-2.3.0
ElasticSearch:elasticsearch-6.3.2
kibana:kibana-6.3.2

用 Canal 實(shí)現(xiàn)數(shù)據(jù) ETL 到 MySQL8

這個(gè)步驟是利用 Canal 從 2 個(gè)獨(dú)立的 MySQL8 數(shù)據(jù)庫(kù)中作喘,抽取需要的表到搜索服務(wù)的 MySQL 數(shù)據(jù)庫(kù)。

①安裝 canaldeployer

解壓 canal.deployer-1.1.4.tar.gz晕城,并配置 canal deployer泞坦。

進(jìn)入 canaldeployer/conf 目錄,修改 canal.properties 文件广辰,主要配置 serverMode暇矫、MQ 和 destination 三部分。

首先择吊,我們 serverMode 修改為 Kafka 模式李根,增加系統(tǒng)緩沖能力以及提高系統(tǒng)穩(wěn)定性:
serverMod

接著,配置 Kafka 的 MQ 信息(Kafka 請(qǐng)自行安裝):


Kafka MQ

最后几睛,配置需要實(shí)例化的 instance房轿,這里配置了 3 個(gè),表示 canal deploy 會(huì)啟動(dòng)這 3 個(gè)實(shí)例所森,同步 MySQL 的 Binlog 到 Kafka 的 Topic 內(nèi)囱持。

如下圖所示:
destinations 實(shí)例配置

配置 canal deployer instance:進(jìn)入 canaldeployer/conf/example 目錄,發(fā)現(xiàn)有一個(gè)instance.properties 文件焕济,這是 Canal 給的示例纷妆,我們可以參考其配置。

我們拷貝整個(gè) example 目錄晴弃,并重命名為上個(gè)步驟配置的 destination 之一掩幢,如 xxxsearch逊拍。

進(jìn)入 xxxsearch 目錄,編輯 instance.properties 文件际邻,主要配置源數(shù)據(jù)庫(kù)信息芯丧、所需數(shù)據(jù)表及字段,以及指定 Kafka 的 Topic 名世曾。

這樣源數(shù)據(jù)庫(kù)的 Binlog 就會(huì)轉(zhuǎn)換為 Json 數(shù)據(jù)缨恒,并實(shí)時(shí)的通過(guò) canal deployer 傳輸?shù)?Kafka 該 Topic 中。

如下所示:

canaldeploy instance 源數(shù)據(jù)庫(kù)配置
canaldeploy instance kafka topic配置

進(jìn)入 canaldeployer/bin 目錄轮听,執(zhí)行 ./startup.sh骗露,啟動(dòng) canal deployer 及所屬實(shí)例。至此 canal deployer 搭建完成蕊程。

②安裝 canal.adapter

我們需要利用 canal.adapter 將 Kafka Topic 中的 binlog json 數(shù)據(jù)椒袍,經(jīng)過(guò)清洗轉(zhuǎn)換等操作驼唱,存儲(chǔ)到 MySQL8 中藻茂。由于 Canal 原生是不支持 MySQL8 的,故我們需要做一些調(diào)整玫恳。

增加 MySQL8 連接驅(qū)動(dòng):解壓 canal.adapter-1.1.4.tar.gz辨赐,進(jìn)入 canaladapter/lib 目錄,移除 mysql-connector-java-5.1.40.jar京办,導(dǎo)入 mysql-connector-java-8.0.18.jar掀序。

配置 canal adapter,使數(shù)據(jù)輸出到 MySQL8:進(jìn)入 canaladapter/conf 目錄惭婿,編輯 application.yml 文件不恭,主要配置消費(fèi) Kafka、源數(shù)據(jù)庫(kù)信息和搜索系統(tǒng)數(shù)據(jù)庫(kù)信息财饥。

如下所示:


ETL 到 MySQL8 配置

接著换吧,進(jìn)入 canaladapter/conf/rdb 目錄,以官方提供的 mytest_user.yml 為例钥星,配置 Kafka Topic 名沾瓦、源數(shù)據(jù)庫(kù)名、源數(shù)據(jù)表名谦炒,以及目標(biāo)數(shù)據(jù)庫(kù)名和目標(biāo)數(shù)據(jù)表名贯莺,建議一張表對(duì)應(yīng)一個(gè) yml 文件。

ETL 表結(jié)構(gòu)映射配置

啟動(dòng) canaladapter:進(jìn)入canaladapter/bin 目錄宁改,執(zhí)行 ./startup.sh缕探,啟動(dòng) canal adapter,觀察 logs/adapter/adapter.log 日志文件还蹲,手動(dòng)在搜索系統(tǒng)數(shù)據(jù)庫(kù)新增一條記錄爹耗,看是否會(huì)打印如下日志豁鲤,即有 2 條記錄,一條 INFO鲸沮,一條 DEBUG琳骡,則表示配置成功。

canaladapter 日志

至此讼溺,數(shù)據(jù) ETL 階段搭建完成楣号,數(shù)據(jù)可從兩個(gè)不同的 MySQL8 數(shù)據(jù)庫(kù),實(shí)時(shí)同步到搜索服務(wù)的 MySQL 數(shù)據(jù)庫(kù)怒坯。

實(shí)現(xiàn)數(shù)據(jù)多表關(guān)聯(lián)炫狱、父子文檔映射

①配置第二個(gè) Canal 的 canaladapter

進(jìn)入 canaladapter/conf 目錄,編輯 application.yml 文件剔猿,主要配置消費(fèi) Kafka视译、搜索系統(tǒng)數(shù)據(jù)庫(kù),和 ES 連接信息归敬。

如下所示:
canaladapter MQ 及 MySQL 配置
canaladapter ES 配置

②配置多表關(guān)聯(lián)

進(jìn)入 canaladapter/conf/es 目錄酷含,vim mytest_user.yml,編輯多表關(guān)聯(lián)配置:

多表關(guān)聯(lián)配置

注意汪茧,sql支持多表關(guān)聯(lián)自由組合, 但是有一定的限制:

  • 主表不能為子查詢(xún)語(yǔ)句椅亚。

  • 只能使用 left outer join 即最左表一定要是主表。

  • 關(guān)聯(lián)從表如果是子查詢(xún)不能有多張表舱污。

  • sql 中不能有 where 查詢(xún)條件(從表子查詢(xún)中可以有 where 條件但是不推薦, 可能會(huì)造成數(shù)據(jù)同步的不一致呀舔,比如修改了 where 條件中的字段內(nèi)容)。

  • 關(guān)聯(lián)條件只允許主外鍵的'='操作不能出現(xiàn)其他常量判斷比如:on a.role_id=b.id and b.statues=1扩灯。

  • 關(guān)聯(lián)條件必須要有一個(gè)字段出現(xiàn)在主查詢(xún)語(yǔ)句中比如:on a.role_id=b.id 其中的 a.role_id 或者 b.id 必須出現(xiàn)在主 select 語(yǔ)句中媚赖。

  • ElasticSearchmapping 屬性與 sql 的查詢(xún)值將一一對(duì)應(yīng)(不支持 select *)。

    比如:select a.id as _id珠插,a.name惧磺,a.email as _email from user,其中 name 將映射到 es mappingname field丧失,_email 將映射到 mapping_email field豺妓,這里以別名(如果有別名)作為最終的映射字段。這里的 _id 可以填寫(xiě)到配置文件的 _id: _id 映射布讹。

③配置父子文檔

以官方的 biz_order.yml 為例琳拭,vim biz_order.yml,配置父子文檔映射:


配置父子文檔映射

④在 ElasticSearch6 中描验,建立 index 和父子文檔映射關(guān)系

進(jìn)入 Kibana 頁(yè)面白嘁,點(diǎn)擊 Dev Tools,執(zhí)行如下命令膘流,即可建立索引及父子文檔映射:

建立 index 和父子文檔映射

其中絮缅,ES6 和 Kibana 的安裝鲁沥,在此無(wú)特別配置,不做贅述耕魄。

⑤啟動(dòng) canal adapter

進(jìn)入 canaladapter/bin 目錄画恰,執(zhí)行 ./startup.sh,啟動(dòng) canal adapter吸奴,觀察 logs/adapter/adapter.log 日志文件允扇,手動(dòng)在搜索系統(tǒng)數(shù)據(jù)庫(kù)新增一條記錄,看是否會(huì)打印如下日志则奥,如打印則表示配置成功考润。


正確配置 adapter 日志示例

運(yùn)行結(jié)果

現(xiàn)在,我們可以通過(guò) Kibana 來(lái)執(zhí)行 DSL 語(yǔ)句來(lái)查詢(xún)看看读处。

我們事先已在商家系統(tǒng)中增加了一個(gè)“肯德基”商店糊治,然后在商品系統(tǒng)中添加了“西紅柿”和“新鮮西紅柿”2 個(gè)商品,并將商品關(guān)聯(lián)到“肯德基”上罚舱。

接著我們查詢(xún)“肯德基”或者“西紅柿”井辜,得到以下是查詢(xún)的結(jié)果(去除了 ES 默認(rèn)字段):

通過(guò) DSL 查詢(xún)的結(jié)果

由圖可見(jiàn),我們可以通過(guò)商家名查詢(xún)商品馆匿,也可通過(guò)商品名查詢(xún)商店和商品抑胎,并且 Canal 支持?jǐn)?shù)據(jù)的實(shí)時(shí)增刪改,所以 ES 的數(shù)據(jù)也會(huì)與商家系統(tǒng)和商品系統(tǒng)保持一致渐北,同時(shí)數(shù)據(jù)結(jié)構(gòu)包含商家及對(duì)應(yīng)的商品,滿(mǎn)足業(yè)務(wù)需求铭拧。

總結(jié)

至此赃蛛,基于 Canal、Kafka搀菩、MySQL8呕臂、ElasticSearch6 技術(shù)的商家商品搜索系統(tǒng)基礎(chǔ)框架搭建完成。

我們采用 canal deployer 實(shí)時(shí)讀取商家肪跋、商品系統(tǒng)的 MySQL 數(shù)據(jù)庫(kù) Binlog歧蒋,并發(fā)送至 Kafka。

接著由 canal adapter 消費(fèi) Kafka州既,并將 binlog json 數(shù)據(jù)進(jìn)行多表關(guān)聯(lián)谜洽、父子文檔映射,最后存儲(chǔ)到 ES6 中吴叶,供上層搜索服務(wù)調(diào)用阐虚。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市蚌卤,隨后出現(xiàn)的幾起案子实束,更是在濱河造成了極大的恐慌奥秆,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件咸灿,死亡現(xiàn)場(chǎng)離奇詭異构订,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)避矢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)鲫咽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人谷异,你說(shuō)我怎么就攤上這事分尸。” “怎么了歹嘹?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,548評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵箩绍,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我尺上,道長(zhǎng)材蛛,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,657評(píng)論 1 293
  • 正文 為了忘掉前任怎抛,我火速辦了婚禮卑吭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘马绝。我一直安慰自己豆赏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,689評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布富稻。 她就那樣靜靜地躺著掷邦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪椭赋。 梳的紋絲不亂的頭發(fā)上抚岗,一...
    開(kāi)封第一講書(shū)人閱讀 51,554評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音哪怔,去河邊找鬼宣蔚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛认境,可吹牛的內(nèi)容都是我干的胚委。 我是一名探鬼主播,決...
    沈念sama閱讀 40,302評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼元暴,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼篷扩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起茉盏,我...
    開(kāi)封第一講書(shū)人閱讀 39,216評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鉴未,失蹤者是張志新(化名)和其女友劉穎枢冤,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體铜秆,經(jīng)...
    沈念sama閱讀 45,661評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淹真,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,851評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了连茧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片核蘸。...
    茶點(diǎn)故事閱讀 39,977評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖啸驯,靈堂內(nèi)的尸體忽然破棺而出客扎,到底是詐尸還是另有隱情戳杀,我是刑警寧澤垒探,帶...
    沈念sama閱讀 35,697評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站惭聂,受9級(jí)特大地震影響针姿,放射性物質(zhì)發(fā)生泄漏袱吆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,306評(píng)論 3 330
  • 文/蒙蒙 一距淫、第九天 我趴在偏房一處隱蔽的房頂上張望绞绒。 院中可真熱鬧,春花似錦榕暇、人聲如沸蓬衡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,898評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)撤蟆。三九已至,卻和暖如春堂污,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背龄砰。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,019評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工盟猖, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人换棚。 一個(gè)月前我還...
    沈念sama閱讀 48,138評(píng)論 3 370
  • 正文 我出身青樓式镐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親固蚤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子娘汞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,927評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容