<del id="nnjnj"></del><track id="nnjnj"></track>

<p id="nnjnj"></p>

<address id="nnjnj"></address>

    <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

      <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>

      • 自動秒收錄
      • 軟件:1973
      • 資訊:56215|
      • 收錄網站:181187|

      IT精英團

      內存數據庫如何利用內存?

      內存數據庫如何利用內存?

      瀏覽次數:
      評論次數:
      編輯: 溫瑜
      信息來源: ITPUB
      更新日期: 2022-05-09 18:32:41
      摘要

      與以磁盤存儲為主的普通數據庫相比,內存數據庫的數據訪問速度可以高出幾個數量級,能大幅提高運算性能,更適合高并發、低延時的業務場景。不過,當前大部分內存數據庫仍然采用SQL模型,而SQL缺乏一些

      • 正文開始
      • 相關閱讀
      • 推薦作品

      與基于磁盤存儲的普通數據庫相比,內存數據庫的數據訪問速度可以高出幾個數量級,可以大幅提升計算性能,更適用于高并發、低延遲的業務場景。但目前大部分內存數據庫仍然采用SQL模型,SQL缺乏一些必要的數據類型和操作,無法充分利用內存的特性來實現一些高性能的算法。簡單地把數據和操作從外存移到內存中,可以取得比外存好得多的性能,但如果不充分利用內存的特性,是無法達到極致性能的。我們來看看有哪些適合內存特性的算法和存儲機制,可以進一步提高內存數據庫的計算速度。指針多路復用

      我們知道,內存是可以通過地址(指針)來訪問的。然而,SQL沒有由內存指針表示的數據對象。當返回結果集時,通常會制作數據的副本以形成新的數據表。這不僅會消耗更多的CPU時間(用于復制數據),還會占用更昂貴的內存空間(用于存儲復制的數據),從而降低內存利用率。除了基于SQL的內存數據庫,Spark中的RDD也有這個問題,而且情況更嚴重。為了保持RDD的不可變特性,Spark在每一個計算步驟后都會復制新的RDD,造成內存和CPU的極大浪費。所以即使消耗了巨大的資源,Spark依然無法實現高性能。相比之下,基于SQL的內存數據庫通常會進行優化,SQL語句中的計算會嘗試使用內存地址,這通常比Spark的要好。但是受限于理論,在實現SQL的邏輯時,必須復制返回的結果集。如果涉及到多步流程操作,就需要在上一步結果集(臨時表)的基礎上多次進行進一步的計算,SQL的劣勢就會很明顯。事實上,如果不改變數據結構,我們可以直接使用原始數據的地址來形成結果集,而不需要復制數據本身,只需多保存一個地址(指針),同時減少CPU和內存的消耗。擴展了SQL的數據類型,支持這種指針式復用機制。例如,根據訂單日期(odate)的范圍過濾訂單表后,分別計算訂單金額(amount1)大于1000和運費(amount2)大于1000的訂單,然后計算兩者的交、并、差,最后根據客戶編號(cid)對差進行排序。SPL電碼大致是這樣的:

      A

      B

      一個

      =orders . select(otate=date(2000,1,1)otate=date(2022,1,1))

      2

      =A1.select(金額11000)

      =A1.select(金額21000)

      =A2^B2

      =A2B2

      =A2\B2

      =B2\A2

      =A4 .排序(cid)

      =B4.sort(cid)

      上面的代碼中有幾個步驟,一些中間結果被多次使用。但由于使用了訂單中記錄的所有指針,所以內存占用增加很少,也避免了記錄復制的耗時。

      外鍵預關聯

      外鍵關聯是指使用一個表(事實表)的非主鍵字段來關聯另一個表(維度表)的主鍵。例如,訂單表中的客戶號和產品號分別與客戶表和產品表的主鍵相關聯?,F實中可能有七張、八張甚至十幾張表之多,可能有多層關聯。SQL數據庫通常使用哈希連接算法進行內存連接,需要計算和比較哈希值。在這個過程中還要占用內存存儲中間結果,關聯表多的時候計算性能會急劇下降。其實我們也可以利用內存指針引用機制,提前做好關聯。在系統的初始階段,事實表中關聯字段的值被轉換為相應維度表記錄的指針。因為維度表的關聯字段是主鍵,所以關聯記錄是唯一的,將外鍵值轉換為記錄指針不會導致錯誤。在后續的計算中,當需要引用維度表字段時,可以通過指針直接引用,不需要計算比較哈希值和存儲中間結果,從而獲得更好的性能。沒有SQL記錄指針的數據類型,就無法實現預關聯。原則上,SPL支持并實施這一預關聯機制。例如,完成訂單表與客戶表和產品表的預關聯的代碼大致如下:

      A

      一個

      =file('customer.btx ')。導入@b()。按鍵@i(c

      id)2=file("product.btx").import@b().keys@i(pid)3=file("orders.btx").import@b().switch(cid,A1;pid,A2)4>env(orders,A3)

      A1、A2 加載客戶表和產品表。

      A3:加載訂單表,將其中的客戶號 cid、產品號 pid 轉換為對應維表記錄的指針。

      A4:將完成預關聯的訂單表存入全局變量,供后續計算使用。系統運行時,按照產品供應商過濾訂單,再按客戶所在城市分組匯總的代碼大致是下面這樣:

      A
      1=orders.select(pid.supplier=="raqsoft.com").groups(cid.city;sum(pid.price*quantity))

      訂單表中的 pid 已經轉換為產品表記錄的指針,所以可以直接用“.”操作符引用產品表記錄。不僅書寫更簡單,而且運算性能也快得多。

      只是兩、三個表關聯時,預關聯和 HASH JOIN 的差別還不是非常明顯。這是因為關聯并不是最終目的,之后還會有其它很多運算,關聯本身運算消耗時間的占比相對不大。但如果關聯情況比較復雜,涉及的表很多,以及有多層的時候(比如訂單關聯產品,產品關聯供應商,供應商關聯城市,城市關聯國家等等),預關聯的性能優勢會更明顯。

      序號定位

      與外存相比,內存的另一個重要特征是支持高速的隨機訪問,可以快速從內存表中按指定序號(也就是位置)取出數據。在做查找計算時,如果被查找的值正好是目標值在內存表中的序號,或者很容易通過被查找值計算出目標值的序號,我們就可以用序號直接取目標記錄。這種方法不需要進行任何比對就能直接取出查找結果,性能不僅遠遠好于遍歷查找,也好于使用索引的查找算法。但是,SQL 以無序集合為基礎,不能按序號取成員,只能用序號去查找。如果沒有索引就只能遍歷查找,會非常慢。即使有索引也要計算 HASH 值或用二分法查找,速度也比不上直接定位。而且,建立索引也會占用昂貴的內存。如果數據表中沒有序號還要先排序再硬造個序號時,性能就會更差。SPL 以有序集合為基礎,提供序號定位功能。比如訂單表中的訂單號是從 1 開始的自然數。在查找訂單號 i 時,直接取訂單表中的第 i 條記錄就行了。再比如數據表 T 從 2000 年到 2022 年每天存儲一條數據,現在需要查詢指定日期的記錄。日期雖然不是目標值的序號,但是我們可以先算出指定日期距離起始日期的天數。這就是目標值的序號,然后再用序號取 T 表記錄就可以了。對表 T 用序號定位查找 2022 年 4 月 20 日記錄的代碼,大致是下面這樣:

      A
      1=date(2022,12,31)-date(1999,12,31)
      2=T_orginal.align@b(to(A1),dt-date(1999,12,31))
      3=env(T,A5)
      4=T(date(2021,4,20)-date(1999,12,31))
      A1:計算出 2000 年到 2022 年總天數是 8401 天。A2:用原始的 T 表記錄計算出距離起始日期的天數,再和 to(A1)這個自然數集合 [1,2,3,…,8401] 對齊,空缺的日期會用 null 補齊。align 的 @b 選項表示對齊時將使用二分法來查找位置,這樣完成對齊動作也會更快一點。A3:計算好的結果,放到全局變量 T 中。A4:要查找 2021 年 4 月 20 日記錄,求出這個日期和起始日期距離 7781 天,直接取出 T 表中第 7781 條記錄就可以了。A1 到 A3 是對齊計算,用于處理空缺的日期,可以放在系統初始化階段。在查找計算時,用 A4 中的序號定位代碼就能得到查找結果,實際查找的日期可以作為參數傳入。

      集群維表

      當數據量太大,超出單機內存時,就要使用集群來加載這些數據。許多內存數據庫也支持分布式計算,通常是將數據分成多段,分別加載到集群不同分機的內存中。JOIN 是分布式計算的一個麻煩任務,會涉及多個分機之間的數據傳輸。嚴重的時候,傳輸造成的延遲會抵消集群分攤計算量得到的好處,會出現集群變大反而性能并不能提升的現象。SQL 體系下的分布式數據庫,通常是將單機 HASH JOIN 方法擴展到集群上。每個分機根據 HASH 值將本機數據分發到其他分機,確保相關聯的數據在同一分機上。然后再在各個分機上做單機連接。但是,HASH 方法在運氣不好的時候,可能會造成數據分配的嚴重不均衡,需要借助外存來緩存這些分發到的數據,否則可能因為內存溢出而導致系統崩潰。但是,內存數據庫的主要特征就是將數據加載到內存中計算,出現外存緩存會嚴重拖慢計算性能。實際上,外鍵關聯的事實表和維表有很大區別。事實表一般都比較大,要用各個分機內存分段加載才能裝的下。正好事實表也比較適合分段,每個分段的數據都相互獨立,分機之間不需要相互訪問。而維表記錄則會被隨機訪問,事實表的任何一個分段都可能關聯全部維表記錄。我們可以利用事實表和維表的區別,對集群的外鍵關聯提速。如果維表比較小,則將維表全量數據復制到所有分機內存中。這樣,每個分機中的事實表分段和全量維表就可以繼續完成預關聯,完全避免了關聯過程中的網絡傳輸。如果維表也很大,單機內存放不下,只能在各分機內存中分段加載。這時,沒有一個分機上有全量的維表,外鍵關聯計算就無法避免網絡傳輸了。不過傳輸內容并不算很大,只涉及事實表的外鍵和維表關聯記錄的字段,事實表其它字段不需要傳輸,計算可以直接完成,過程中也不會產生緩存數據。SPL 從原理上區分維表和事實表,針對維表較小和維表較大兩種情況,分別提供了維表復制機制和分段維表機制,實現了上述算法,能顯著提高集群情況下外鍵關聯的計算性能。

      備胎式容錯

      集群系統必須要考慮容錯,內存數據的容錯和外存是不同的。外存一般使用副本的方法,即同一份數據有多個副本,某個分機失效后仍然能在其它分機找到數據。這種機制的存儲利用率很低,只有 1/k(k 是副本數量)。但是,對于內存中的數據,卻不能使用這種副本容錯方法。這是因為硬盤足夠便宜且幾乎可以無限擴容,但是內存要昂貴的多而且擴容有上限。只有 1/k 的內存利用率是無法容忍的。內存容錯需要不同于外存的專門手段。SPL 提供了備胎式容錯機制,將數據分成 n 段后分別加載到 n 個分機的內存中。然后準備 k 個空閑的分機作為備用機。當正在運行的某個分機失效時,則立即啟用某個備用機,臨時加載失效分機的數據,和其它分機重新組成擁有完整數據的集群繼續提供服務。失效的分機排除故障后恢復使用,可以再充當備用機。整個過程和汽車更換備胎的模式很像。備胎式容錯機制的內存利用率可以高達 n/(n+k),遠遠高于副本式容錯的 1/k。能加載進內存的數據量通常不會非常大,分機失效后臨時加載的時間并不多,集群服務就可以較快地恢復。

      回顧與總結

      內存數據庫的計算體系,必須充分利用內存的特征才能獲得極致性能。從數據計算的角度來看,內存主要優點有:支持指針引用、支持高速隨機訪問、并發讀取能力強。內存的缺點是:成本高昂、擴容有上限。而 SQL 計算體系中缺乏一些必要的數據類型和運算,比如:缺少記錄指針類型,不支持有序運算,JOIN 定義過于籠統,不區分 JOIN 類型等,從原理上就不能充分利用內存的上述特征實現某些高速算法?;?SQL 的內存數據庫,通常只是簡單的照搬外存數據結構和運算,會出現各種問題。比如:記錄式復制過多消耗 CPU 和內存;查找和 JOIN 性能沒有達到極致。再比如集群方面:內存利用率過低;大量網絡傳輸導致分機數量增加但性能反而下降;多機 JOIN 出現外存緩存等等。開源數據計算引擎 SPL 擴展了數據類型和運算定義,可以充分利用內存的特征,從而實現多種高性能算法,讓性能達到極致。其中,指針式復用利用內存特有的指針引用機制,節省了內存空間,而且速度更快。預關聯同樣利用指針引用機制,在初始化階段完成很耗時的外鍵關聯,后續計算中直接使用關聯好的結果,計算速度顯著提高。序號定位利用有序性,充分發揮內存高速隨機訪問的優勢,不用做任何計算和比對,直接用序號讀取記錄,性能好于 HASH 索引等查找算法。集群維表有效避免或減少了網絡傳輸、避免了外存緩存,備胎式容錯在保證高可用性的前提下,有效提高了集群內存利用率。除此之外,SPL 還提供了排號鍵、序號索引、數據類型壓縮等等其它方法。程序員可以根據具體的場景,有針對性的采用這些方法,就能充分發揮內存的優勢,從而有效提升內存數據計算的性能。

      原文

      標簽:內存 數據 分機
      解決緩存崩潰問題的一行代碼
      ? 上一篇 2022-05-09
      運維常用的34個Linux Shell腳本 對你一定有幫助!
      下一篇 ? 2022-05-09
      • 胡迪核心知識點詳解(好文章合集)
        1閱讀 0條評論 個贊
        以下文章來源于公眾號-3分鐘秒懂大數據,作者在IT中穿梭旅行在Flink實時流中,經常會通過FlinkCDC插件讀取Mysql數據,然后寫入Hudi中。所以在執行上述操作時,需要了解……
      • 前端面試必須解決網絡中的跨域問題
        0閱讀 0條評論 個贊
        什么是跨域瀏覽器有一個重要的安全策略,稱之為「同源策略」其中,源=協議+主機+端口源=協議+主機+端口源=協議+主機+端口,兩個源相同,稱之為同源,兩個源不同,稱之為跨源或跨域比如:源1源2是否同……
      • 如何在Bash腳本中使用強大的Linux測試命令
        0閱讀 0條評論 個贊
        Linuxtest命令是Shell內置命令,用來檢測某個條件是否成立。test通常和if語句一起使用,并且大部分if語句都依賴test??梢詫⒁粋€元素與另一個元素進行比較,但它更?!?/div>
      • 真正的建筑設計是什么樣子的?
        1閱讀 0條評論 個贊
        什么是架構和架構本質在軟件行業,對于什么是架構,都有很多的爭論,每個人都有自己的理解。此君說的架構和彼君理解的架構未必是一回事。因此我們在討論架構之前,我們先討論架構的概念定義,概念是人認識這個世界的……
      • 10分鐘了解云原生 值得收藏~
        0閱讀 0條評論 個贊
        文章轉載:奇妙的Linux世界我們已經進入云計算下半場,不再像上半場在糾結要不要上云,而是討論怎么上云?才能把云計算的價值發揮到淋漓盡致。如何把云計算與不同的業務場景深度結合?如何讓技術真正作用于企業……
      發表評論 共有條評論
      用戶名: 密碼:
      驗證碼: 匿名發表
      • 在Linux中檢查磁盤空間的12個有用的df命令
        1閱讀 0條評論 個贊
        1.檢查文件系統磁盤空間使用情況這df命令顯示文件系統上的設備名稱、總塊數、總磁盤空間、已用磁盤空間、可用磁盤空間和掛載點信息。[root@local~]#dfFilesystem1K-bloc……
      • 說說春云的全鏈路灰度發布方案~
        1閱讀 0條評論 個贊
        以下文章來源于公眾號-碼猿技術專欄,作者不才陳某大家好實際生產中如有需求變更,并不會直接更新線上服務,最通常的做法便是:切出線上的小部分流量進行體驗測試,經過測試后無問題則全面的上線。這樣做的好處也是……
      • MySQL的行格式是什么?
        1閱讀 0條評論 個贊
        行格式(rowformat)決定了我們插入的一行數據,是如何存儲在數據庫中的,MySQL有4種行格式,分別是REDUNDANT,COMPACT,DYNAMIC,COMPRESSED。不同行格式區別:……
      • 基礎鞏固——至少需要多少行代碼才能實現深度復制?
        1閱讀 0條評論 個贊
        前言深度克?。ㄉ羁截悾┮恢倍际浅?、中級前端面試中經常被問到的題目,網上介紹的實現方式也都各有千秋,大體可以概括為三種方式:JSON.stringify+JSON.parse,這個很好理解;全量判斷類……
      • 低代碼實時倉儲系統的設計與實踐
        1閱讀 0條評論 個贊
        1導讀本文介紹58信安基于Flink實現低代碼實時數倉構建系統,我們將數倉構建這一過程進行抽象,通過工程化的思想去解決,將固有領域問題交給系統,讓開發人員關注數據本身,解放人力縮短數倉構建周期。2背景……
      • Linux最常用的命令:解決95%以上的問題
        1閱讀 0條評論 個贊
        Linux是目前應用最廣泛的服務器操作系統,基于Unix,開源免費,由于系統的穩定性和安全性,市場占有率很高,幾乎成為程序代碼運行的最佳系統環境。linux不僅可以長時間的運行我們編寫的程序代碼,還可……
      • 1972年的C語言 控制了Windows、Linux、macOS等操作系統的半邊天
        1閱讀 0條評論 個贊
        來源|CSDN(ID:CSDNnews)誕生于1972年的C語言已經50歲了,目前來看,它還像20歲的小伙一樣活力四射,似乎永不會退休,并且正在賦能全世界重量級應用系統的運行。盡管C語言面世多年,……
      • 如何用10行bash shell腳本監控Linux?
        1閱讀 0條評論 個贊
        http://985.so/xbtd子沐愛掃地(譯)監控我們的環境對于服務器運維來說至關重要,尤其是在部署新的應用程序時。如今,公司每天都使用開源解決方案來監控系統資源。但是,當出于測試的目的來監控……
      • 你可能不知道PostgreSQL能做的8件有趣的事!
        0閱讀 0條評論 個贊
        1整行引用您是否嘗試過運行以下語句?SELECTmy_tableFROMmy_table;這可能看起來很奇怪,但它所做的是將所有列作為行類型返回到單個列中?,F在你為什么要這樣做?好吧,您很可……
      • Spring云應用的優雅下線和灰度發布
        2閱讀 0條評論 個贊
        前言在生產環境中,如何保證在服務升級的時候,不影響用戶的體驗,這個是一個非常重要的問題。如果在我們升級服務的時候,會造成一段時間內的服務不可用,這就是不夠優雅的。那什么是優雅的呢?主要就是指在服務升級……
      • 談如何設計未來的倉庫建筑
        4閱讀 0條評論 個贊
        編輯:數據社全文共3758個字,建議10分鐘閱讀大家好,我是峰哥,夏天已經來了,小麥馬上要豐收了,今天分析一篇關于未來數倉架構發展方向的文章。Linked大佬JayKreps曾發表過一篇博客,簡單闡……
      • 卡夫卡3.0新功能全暴露 好香??!
        1閱讀 0條評論 個贊
        以下文章來源于云加社區,作者屈志平導語|kafka3.0的版本已經試推行去zk的kafka架構了,如果去掉了zk,那么在kafka新的版本當中使用什么技術來代替了zk的位置呢,接下來我們一起來一探究竟……
      • MySQL批量插入數據 一次插入多少行數據效率最高?
        7閱讀 0條評論 個贊
        一、前言我們在操作大型數據表或者日志文件的時候經常會需要寫入數據到數據庫,那么最合適的方案就是數據庫的批量插入。只是我們在執行批量操作的時候,一次插入多少數據才合適呢?假如需要插入的數據有百萬條,那……
      • 用Ansible實現MySQL的備份、操作和維護
        0閱讀 0條評論 個贊
        作者簡介曹杰,中國結算上海分公司高級經理,從事系統運維管理工作。本文以容器形式部署了開源自動化運維工具Ansible,基于自帶的MySQL管理模塊編排了playbook配置文件,最終實現M……
      • 高可用性架構設計的無狀態服務
        2閱讀 0條評論 個贊
        笑談架構設計事故的發生是量的積累的結果,任何事情都沒有表面看起來那么簡單,在軟件運行的過程中,隨著用戶量的增加,不考慮高可用,遲早有一天會發生故障,不得事先考慮高可用設計,而高可用是一門龐大的學問。在……
      • 如何優雅地升級Kubernetes集群的Docker和Containerd版本
        1閱讀 0條評論 個贊
        前言公司用的k8s集群是“多環境合一”的方式,集群流量入口也摒棄了常見的traefik和ingress-nginx,直接用了一個國內不常見的底層基于Envoy的APIGateway網關服務。當然還有……
      • MySQL 5.7 和 8.0 幾處細節上的差異
        9閱讀 0條評論 個贊
        MySQL8.0相對于MySQL5.7,有很多新特性,比如:快速加列、原子DDL、不可見索引、額外端口、角色管理等。這一節內容,就不講這些新特性了,只來聊聊最近在工作學習過程中遇到的幾處細節……
      • 如何讓Kubernetes集群優雅地使用GPU節點
        2閱讀 0條評論 個贊
        如何讓你的Kubernetes集群使用GPU節點CUDA驅動程序如果您還沒有這樣做,請確保您已在GPU節點上安裝了NVIDIACUDA驅動程序。CUDA是來自nvidia的并行計算平臺。ht……
      • 一行Python代碼實現程序并行
        1閱讀 0條評論 個贊
        Python在程序并行化方面多少有些聲名狼藉。撇開技術上的問題,例如線程的實現和GIL,我覺得錯誤的教學指導才是主要問題。常見的經典Python多線程、多進程教程多顯得偏"重"。而且往往隔靴搔……
      • 關于數據中心最強科普 一個就給你完整了解!
        1閱讀 0條評論 個贊
        數據中心,英文縮寫叫IDC,也就是InternetDataCenter(互聯網數據中心)。之所以不太直接稱之為“DC”,主要是為了避免和直流電(DirectCurrent)混淆。而且,現在的數……
      最近發布資訊
      更多
      警花高潮嗷嗷叫
      <del id="nnjnj"></del><track id="nnjnj"></track>

      <p id="nnjnj"></p>

      <address id="nnjnj"></address>

        <pre id="nnjnj"><pre id="nnjnj"></pre></pre>

          <noframes id="nnjnj"><ruby id="nnjnj"><ruby id="nnjnj"></ruby></ruby>