欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot實(shí)現(xiàn)海量數(shù)據(jù)高效實(shí)時(shí)搜索功能

 更新時(shí)間:2023年10月23日 09:53:17   作者:shepherd111  
我們都知道隨著業(yè)務(wù)系統(tǒng)的發(fā)展和使用,數(shù)據(jù)庫存儲(chǔ)的業(yè)務(wù)數(shù)據(jù)量會(huì)越來越大,逐漸成為了業(yè)務(wù)系統(tǒng)的瓶頸,本文給大家介紹了Spring Boot業(yè)務(wù)系統(tǒng)如何實(shí)現(xiàn)海量數(shù)據(jù)高效實(shí)時(shí)搜索,文中有詳細(xì)的代碼示例,需要的朋友可以參考下

1.概述

我們都知道隨著業(yè)務(wù)系統(tǒng)的發(fā)展和使用,數(shù)據(jù)庫存儲(chǔ)的業(yè)務(wù)數(shù)據(jù)量會(huì)越來越大,逐漸成為了業(yè)務(wù)系統(tǒng)的瓶頸。在阿里巴巴開發(fā)手冊(cè)中也建議:單表行數(shù)超過500萬行或者單表容量超過2GB才推薦進(jìn)行分庫分表,如果預(yù)計(jì)三年后數(shù)據(jù)量根本達(dá)不到這個(gè)級(jí)別,請(qǐng)不要在創(chuàng)建表時(shí)就分庫分表。數(shù)據(jù)庫最終都是存儲(chǔ)在磁盤上,隨著數(shù)據(jù)量變大,會(huì)導(dǎo)致數(shù)據(jù)操作變得緩慢,無論是計(jì)算還是IO,但是話又說回來,單表數(shù)據(jù)量大就一定要進(jìn)行分庫分表操作嗎?答案是否定的,因?yàn)榉謳旆直肀旧硎且粋€(gè)“很重”的操作,這里就不賣關(guān)子了,直接來看看分庫分表帶來的以下問題和挑戰(zhàn):

  • 重構(gòu)適配系統(tǒng) 本身我們的業(yè)務(wù)系統(tǒng)不可能一開始開發(fā)上線的時(shí)候就會(huì)分庫分表,都是隨著系統(tǒng)使用和時(shí)間推移數(shù)據(jù)量日益膨脹才考慮的,進(jìn)行分庫分表我們業(yè)務(wù)服務(wù)項(xiàng)目代碼需要從單一數(shù)據(jù)庫表適配成多庫多表,這是一次極其繁重的重構(gòu)任務(wù),還涉及到數(shù)據(jù)遷移、備份、擴(kuò)容等操作問題,該任務(wù)上線鏈路之長、風(fēng)險(xiǎn)之大不言而喻,這也是很多小公司即使數(shù)據(jù)量上來了也不會(huì)馬上分庫分表的原因吧。
  • 事務(wù)問題 目前數(shù)據(jù)庫只能夠?qū)崿F(xiàn)本地事務(wù),也就是在同一個(gè)數(shù)據(jù)庫中,可以允許一組操作要么全都正確執(zhí)行,要么都不執(zhí)行,從而確保數(shù)據(jù)庫的一致性。單從分區(qū)角度出發(fā),實(shí)際上仍然是一張表,一個(gè)庫中,它不會(huì)存在事務(wù)一致性的問題,但是會(huì)使得事務(wù)變得非常復(fù)雜。而分庫分表會(huì)涉及到分布式事務(wù),目前數(shù)據(jù)庫并不支持跨庫事務(wù),所以在這一塊需要解決分布式事務(wù)可能帶來的不一致性
  • 分頁、排序、聚合函數(shù)問題 分頁需要按照?qǐng)?zhí)行的字段進(jìn)行排序,當(dāng)排序字段就是分片字段的時(shí)候,通過分片規(guī)則就比較容易定位到指定的分片;當(dāng)排序字段并非分片字段的時(shí)候,就需要在不同分區(qū)、分表中進(jìn)行排序并且返回,然后再將不同分區(qū)、分表中返回的結(jié)果集進(jìn)行匯總和再次排序,最終得到返回結(jié)果。取得頁數(shù)越多,性能受影響也就越大。因?yàn)樵诜謪^(qū)、分表的時(shí)候都已經(jīng)限定了分片字段,而其他字段是跟著分片的字段被分到不同的區(qū)域或者表中,這樣各個(gè)分區(qū)、分表中的數(shù)據(jù)可能是隨機(jī)的,為了排序的準(zhǔn)確性,需要將所有分區(qū)、分表節(jié)點(diǎn)的前的數(shù)據(jù)都排好序做合并,最后進(jìn)行整體排序,這樣的操作是非常耗費(fèi)CPU和內(nèi)存資源的,所以在分區(qū)、分表的情況下、分頁數(shù)越大,系統(tǒng)的性能也會(huì)越差。同樣、在使用聚合函數(shù),如Max、Min、Sum、Count進(jìn)行計(jì)算的時(shí)候,也會(huì)像排序那樣在每個(gè)分區(qū)、分表執(zhí)行相應(yīng)的函數(shù),然后再將各個(gè)分區(qū)、分表的結(jié)果集進(jìn)行匯總和再次計(jì)算,最終將結(jié)果返回。
  • 全局主鍵避免重復(fù) 單表主鍵id自增能夠保證id不重復(fù),但是分庫分表之后,多張表就不能保證主鍵id不重復(fù)了,這時(shí)候就要使用分布式id算法進(jìn)行生成。
  • 數(shù)據(jù)遷移、擴(kuò)容問題 隨著數(shù)據(jù)持續(xù)增加分表后還需要進(jìn)行動(dòng)態(tài)新增表時(shí),這個(gè)時(shí)候就要考慮數(shù)據(jù)遷移以及擴(kuò)容問題。一般做法是先讀出歷史數(shù)據(jù),然后按照指定的分表規(guī)則再將數(shù)據(jù)寫入各個(gè)分表中。這本身就是繁雜之事。

當(dāng)然以上問題并不是說分庫分表是一個(gè)不可取的方案,現(xiàn)在分庫分表方案在很多公司系統(tǒng)都有應(yīng)用的,這里想表達(dá)的是需要根據(jù)個(gè)人公司業(yè)務(wù)系統(tǒng)數(shù)據(jù)特點(diǎn),綜合評(píng)估做權(quán)衡來選擇解決數(shù)據(jù)量大的實(shí)施方案。

2.業(yè)務(wù)數(shù)據(jù)量大的解決方案

2.1 數(shù)據(jù)歸檔

來分析一個(gè)美團(tuán)業(yè)務(wù)場景:我們?nèi)粘C刻禳c(diǎn)外賣,平時(shí)會(huì)去查看一年前的訂單,看看一年前吃了什么嗎?答案是幾乎不會(huì),或者說這種查詢的請(qǐng)求量比較小,出現(xiàn)這種請(qǐng)求大概是有人問你很早之前點(diǎn)的那家外賣好吃,但是你不喜歡記不得了,你幫她查找一下的場景吧~~。由此可見,我們可以根據(jù)這一特點(diǎn)進(jìn)行數(shù)據(jù)歷史歸檔,即數(shù)據(jù)做冷、熱區(qū)分存儲(chǔ)。當(dāng)然這個(gè)區(qū)分時(shí)限要根據(jù)自身系統(tǒng)數(shù)據(jù)特點(diǎn)來指定時(shí)限是一年還是半年....這樣就能保證我們高頻查詢的熱數(shù)據(jù)量不大了。

在查詢歷史數(shù)據(jù)表時(shí),可以限制查詢條件如必須選擇日期范圍,日期范圍不能超過N個(gè)月等等從而減輕查詢壓力。處理歷史存量數(shù)據(jù)比較簡單,因?yàn)闅v史數(shù)據(jù)一般不會(huì)變更了,所以一般只需要兩個(gè)步驟進(jìn)行歸檔:

  • 遷移滿足限定數(shù)據(jù)到指定歷史歸檔表
  • 根據(jù)主鍵分批刪除業(yè)務(wù)原表數(shù)據(jù),從而降低業(yè)務(wù)數(shù)據(jù)量

這里需要強(qiáng)調(diào)一下,不能一次性刪除所有數(shù)據(jù),因?yàn)閿?shù)據(jù)量太大可能會(huì)引發(fā)超時(shí),鎖表,長事務(wù)等問題,而是應(yīng)該根據(jù)ID分批刪除,例如每次刪除500或1000條數(shù)據(jù)。操作步驟如下:

SELECT MAX(id) AS maxId FROM t WHERE create_time < '指定時(shí)間'

查出滿足歸檔條件的數(shù)據(jù)最大id,接下來就可以分批歸檔和刪除了,初始化 startId=0,每次歸檔500條

select * into t_bak from t where id > startId and id <= maxId limit 500

查詢歸檔表獲取最大id:maxBakId,賦值給startId方便下次分批歸檔刪除

select max(id) from t_bak 

數(shù)據(jù)刪除:

delete from t where id <= maxBakId

重復(fù)上面的歸檔刪除操作,直至startId到maxId結(jié)束

2.2 讀寫分離和熱點(diǎn)緩存

大部分的業(yè)務(wù)系統(tǒng)場景都是讀多寫少,讀寫比一般都在幾十左右,平均每發(fā)生幾十次查詢請(qǐng)求,才有一次更新請(qǐng)求。換句話來說,數(shù)據(jù)庫需要應(yīng)對(duì)的絕大部分請(qǐng)求都是只讀查詢請(qǐng)求。針對(duì)這種情況我們可以通過讀寫分離方案來降低數(shù)據(jù)庫壓力。

主庫負(fù)責(zé)執(zhí)行應(yīng)用程序發(fā)來的所有數(shù)據(jù)更新請(qǐng)求,然后異步將數(shù)據(jù)變更實(shí)時(shí)同步到所有的從庫中去,這樣,主庫和所有從庫中的數(shù)據(jù)是完全一樣的。多個(gè)從庫共同分擔(dān)應(yīng)用的查詢請(qǐng)求。

對(duì)于一些高頻訪問的熱點(diǎn)數(shù)據(jù),我們可以提前預(yù)處理使用redis緩存,這樣也可以有效降低數(shù)據(jù)庫的壓力。

2.3 同步異構(gòu)數(shù)據(jù)源

我們知道MySQL會(huì)隨著數(shù)據(jù)量增大而查詢變慢,那么我們換成其他數(shù)據(jù)源來完成OLAP查詢場景不就得了。特別是在當(dāng)下大數(shù)據(jù)時(shí)代,現(xiàn)在互聯(lián)網(wǎng)公司一般都具備與之規(guī)模相對(duì)應(yīng)的大數(shù)據(jù)服務(wù)或者平臺(tái),那么作為業(yè)務(wù)開發(fā)者要善于應(yīng)用公司大數(shù)據(jù)能力,減輕業(yè)務(wù)數(shù)據(jù)庫壓力。比如我們可以把數(shù)據(jù)同步到ES、HBASE等平臺(tái)。

使用elasticsearch來實(shí)現(xiàn)海量數(shù)據(jù)搜索就是一個(gè)不錯(cuò)的選擇,elasticsearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java開發(fā)的,并作為Apache許可條款下的開放源碼發(fā)布,是當(dāng)前流行的企業(yè)級(jí)搜索引擎。能夠達(dá)到實(shí)時(shí)搜索,穩(wěn)定,可靠,快速,安裝使用方便。但是如何實(shí)現(xiàn)MySQL數(shù)據(jù)同步elasticsearch呢?

答案是阿里的開源項(xiàng)目Canal,就是用來解決異構(gòu)數(shù)據(jù)源數(shù)據(jù)同步這個(gè)問題的,Canal項(xiàng)目利用了MySQL數(shù)據(jù)庫主從同步的原理,將Canal Server模擬成一臺(tái)需要同步的從庫,從而讓主庫將binlog日志流發(fā)送到Canal Server接口。Canal項(xiàng)目對(duì)binlog日志的解析進(jìn)行了封裝,我們可以直接得到解析后的數(shù)據(jù),而不需要理會(huì)binlog的日志格式。而且Canal項(xiàng)目整合了zookeeper,整體實(shí)現(xiàn)了高可用,可伸縮性強(qiáng)

2.4 分庫分表

如果通過以上:歷史數(shù)據(jù)歸檔、數(shù)據(jù)同步異構(gòu)數(shù)據(jù)源、讀寫分離、熱點(diǎn)緩存都不能解決MySQL單表數(shù)據(jù)壓力的,這時(shí)我們只能拆分?jǐn)?shù)據(jù)表,即把單庫單表數(shù)據(jù)遷移到多庫多表中。這也是一線流量互聯(lián)網(wǎng)公司需要面對(duì)的,你試想一下淘寶雙11那幾天要上架多少商品,產(chǎn)生多少訂單,這已經(jīng)不是前面的方案所能解決了,只能分庫分表了。當(dāng)然分庫分表是一個(gè)復(fù)雜的操作,也不是三言兩語就能全面講清楚的,且也不是我們今天主要議題,所以我這里粗略概述一下,感興趣的可自行查閱相關(guān)資料。

垂直拆分

垂直拆分就是按照業(yè)務(wù)拆分,我們將電商數(shù)據(jù)庫拆分成三個(gè)庫,訂單庫、商品庫。支付庫,訂單表在訂單庫,商品表在商品庫,支付表在支付庫。這樣每個(gè)庫只需要存儲(chǔ)本業(yè)務(wù)數(shù)據(jù),物理隔離不會(huì)互相影響。

水平拆分

按照垂直拆分方案,現(xiàn)在我們已經(jīng)有三個(gè)庫了,平穩(wěn)運(yùn)行了一段時(shí)間。但是隨著業(yè)務(wù)增長,每個(gè)單庫單表的數(shù)據(jù)量也越來越大,逐漸到達(dá)瓶頸。

這時(shí)我們就要對(duì)數(shù)據(jù)表進(jìn)行水平拆分,所謂水平拆分就是根據(jù)某種規(guī)則將單庫單表數(shù)據(jù)分散到多庫多表,從而減小單庫單表的壓力。

水平拆分策略有很多方案,最重要的一點(diǎn)是選好ShardingKey,也就是按照哪一列進(jìn)行拆分,怎么分取決于我們?cè)L問數(shù)據(jù)的方式。

比如我們可以根據(jù)時(shí)間范圍分片,根據(jù)創(chuàng)建時(shí)間分配到不同的表中。也可以根據(jù)哈希分表,哈希分片可以較為均勻?qū)?shù)據(jù)分散在數(shù)據(jù)庫中。我們現(xiàn)在將訂單庫拆分為4個(gè)庫編號(hào)為[0,3],每個(gè)庫4張表編號(hào)為[0,3],根據(jù)分布式id%編號(hào)落庫,當(dāng)然也有其他分片方案,這取決于你們公司業(yè)務(wù)數(shù)據(jù)特點(diǎn)。

3.如何實(shí)時(shí)同步數(shù)據(jù)到elasticsearch支持海量查詢

我一開始就強(qiáng)調(diào)了分庫分表帶來的問題,可見今天的重點(diǎn)肯定不是采用分庫分表來解決數(shù)據(jù)量大的問題的,所以我接下來來講講我司的解決方案:數(shù)據(jù)歸檔+讀寫分離+同步異構(gòu)數(shù)據(jù)源

數(shù)據(jù)歸檔可以有效降低數(shù)據(jù)庫數(shù)據(jù)量,讀寫分離可以降低單數(shù)據(jù)庫的讀寫壓力,異構(gòu)數(shù)據(jù)源es滿足日常查詢性能要求。

數(shù)據(jù)歸檔的操作步驟前面說過了,至于數(shù)據(jù)庫讀寫分離實(shí)現(xiàn)方案等后續(xù)有時(shí)間再分析一波,今天主要講講如何高效實(shí)時(shí)同步elasticsearch滿足查詢要求。直接看架構(gòu)圖:

數(shù)據(jù)同步elasticsearch大概有兩種:

1.針對(duì)代碼中進(jìn)行數(shù)據(jù)庫的增刪改操作時(shí),同時(shí)進(jìn)行elasticsearch的增刪改操作。這種方式代碼侵入性強(qiáng),耦合度高,實(shí)時(shí)性高,改造起來比較痛苦,因?yàn)槟悴荒苠e(cuò)過任何一個(gè)增刪改的地方同步操作es,否則就會(huì)出現(xiàn)數(shù)據(jù)不一致問題。

2.利用監(jiān)聽mysql binlog同步,實(shí)時(shí)性強(qiáng),對(duì)于應(yīng)用無任何侵入性,且性能更好,不會(huì)造成資源浪費(fèi)。正好阿里巴巴開源的canal就是干這個(gè)的,完美解決問題。通過上面的架構(gòu)圖知道可以通過canal client拿到canal server對(duì)binlog的解析直接同步到es,但是這種方式處理比較慢,等于我們是一條一條的去同步,很多情況下es的索引表是一張大寬表,是來自MySQL幾張表join的信息,這要求我們同步的時(shí)候還要根據(jù)主鍵通過join sql語句查出數(shù)據(jù)再同步,自然就更慢了。所以要使用消息隊(duì)列kafka進(jìn)行數(shù)據(jù)削峰填谷,批量操作是保證實(shí)時(shí)性的關(guān)鍵。

4.總結(jié)

以上全部就是我們對(duì)海量數(shù)據(jù)實(shí)時(shí)搜索的解決方案淺析,各有利弊。我們可以根據(jù)自身的業(yè)務(wù)數(shù)據(jù)情況選擇合適的方案即可,切勿動(dòng)不動(dòng)就來分庫分表,顯得有點(diǎn)不知深淺。

到此這篇關(guān)于SpringBoot實(shí)現(xiàn)海量數(shù)據(jù)高效實(shí)時(shí)搜索功能的文章就介紹到這了,更多相關(guān)SpringBoot實(shí)現(xiàn)數(shù)據(jù)實(shí)時(shí)搜索內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java Volatile 變量詳解及使用方法

    Java Volatile 變量詳解及使用方法

    這篇文章主要介紹了Java Volatile 變量詳解及使用方法的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • Java實(shí)現(xiàn)三子棋游戲

    Java實(shí)現(xiàn)三子棋游戲

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 2020最新IDEA SpringBoot整合Dubbo的實(shí)現(xiàn)(zookeeper版)

    2020最新IDEA SpringBoot整合Dubbo的實(shí)現(xiàn)(zookeeper版)

    這篇文章主要介紹了2020最新IDEA SpringBoot整合Dubbo(zookeeper版),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • Spring中使用JSR303請(qǐng)求約束判空的實(shí)現(xiàn)

    Spring中使用JSR303請(qǐng)求約束判空的實(shí)現(xiàn)

    這篇文章主要介紹了Spring中使用JSR303請(qǐng)求約束判空的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • 利用Spring JPA中的@Version注解實(shí)現(xiàn)樂觀鎖

    利用Spring JPA中的@Version注解實(shí)現(xiàn)樂觀鎖

    樂觀鎖是數(shù)據(jù)庫和應(yīng)用程序中使用的一種并發(fā)控制策略,用于在多個(gè)事務(wù)嘗試更新單個(gè)記錄時(shí)確保數(shù)據(jù)完整性,Java Persistence API (JPA) 提供了一種借助@Version注解在 Java 應(yīng)用程序中實(shí)現(xiàn)樂觀鎖的機(jī)制,文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下
    2023-11-11
  • Java中的instanceof關(guān)鍵字在Android中的用法實(shí)例詳解

    Java中的instanceof關(guān)鍵字在Android中的用法實(shí)例詳解

    instanceof是Java的一個(gè)二元操作符,和==,>,<是同一類東西。接下來通過本文給大家介紹Java中的instanceof關(guān)鍵字在Android中的用法,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧
    2016-07-07
  • elasticsearch分布式及數(shù)據(jù)的功能源碼分析

    elasticsearch分布式及數(shù)據(jù)的功能源碼分析

    這篇文章主要為大家介紹了elasticsearch分布式及數(shù)據(jù)功能源碼分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • Java攔截過濾器模式 (Intercepting Filter )實(shí)現(xiàn)方法

    Java攔截過濾器模式 (Intercepting Filter )實(shí)現(xiàn)方法

    攔截過濾器模式(Intercepting Filter Pattern)用于對(duì)應(yīng)用程序的請(qǐng)求或響應(yīng)做一些預(yù)處理/后處理,本文通過實(shí)例代碼介紹Java攔截過濾器模式 (Intercepting Filter )的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Java數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表深入理解

    Java數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表深入理解

    這篇文章主要介紹了Java數(shù)據(jù)結(jié)構(gòu)與算法之單鏈表深入理解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • Java中6種單例模式寫法代碼實(shí)例

    Java中6種單例模式寫法代碼實(shí)例

    這篇文章主要介紹了Java中6種單例模式寫法代碼實(shí)例,某個(gè)類任何情況下只有一個(gè)實(shí)例,并提供一個(gè)全局訪問點(diǎn)來獲取該實(shí)例,Java6種單例模式有2種懶漢式,2種餓漢式,靜態(tài)內(nèi)部類 ,枚舉類,需要的朋友可以參考下
    2024-01-01

最新評(píng)論