主頁 > 資料庫 > Redis - 底層資料結構

Redis - 底層資料結構

2023-04-12 09:54:42 資料庫

簡介

Redis 的底層資料結構主要以下幾種:

  • SDS(Simple Dynamic String, 簡單動態字串)
  • ZipList(壓縮串列)
  • QuickList(快表)
  • Dict(字典)
  • IntSet(整數集合)
  • ZSkipList(跳躍表)

簡單動態字串

在 Redis 中,并不會直接使用 C 語言自帶的字串結構作為實際的存盤結構,而只是將字串作為字面量使用,大多數情況使用自定義的 SDS 來表示字串,

SDS 主要用于儲存 Redis 的默認字串表示、AOF 模塊中的 AOF 緩沖區、客戶端狀態輸入緩沖區,它的定義如下:

struct sdshdr {
    int len;        // 記錄 buf 陣列中已使用位元組的數量,等于 SDS 所保存的字串的長度
    int alloc;      // 記錄 buf 陣列中未使用位元組的數量
    char buf[];     // 位元組陣列,用于保存字串
};

優點

相對于 C 語言的字串實作,Redis 實作的 SDS 有以下優點:

  • 通過記錄 len 屬性,實作常數級時間復雜度獲取字串長度
  • 通過檢查 len 屬性,避免字串在修改時出現緩沖區溢位的情況
  • 通過記錄 len 屬性和 alloc 屬性,對于修改字串實作了空間預分配和惰性空間釋放
  • 實際存盤的 buf 是一個位元組陣列,可以實作 SDS 安全操作二進制資料
  • SDS 仍然以 \0 作為字串結尾的標識,這樣可以重用 C 語言字串的部分函式

空間預分配

當 SDS 修改時需要擴展空間大小,程式不僅會為 SDS 擴展修改所需的空間,還會為 SDS 分配額外的未使用空間,這額外空間一般是 len 的大小,最大不超過 1MB,

這樣可以減少連續執行字串增長操作所需的記憶體重分配次數,

惰性空間釋放

當 SDS 修改時需要縮短空間大小,程式并不會立即將多出來的空間進行空間重分配,而是使用 alloc 屬性將這些空間大小記錄下來,以待后續使用,

而且 SDS 也提供手動釋放未使用空間的方法,這樣可以避免浪費記憶體,

壓縮串列

ZipList 實際是由一系列特殊編碼的連續記憶體塊組成的順序型資料結構,是 Hash 型別底層實作的一種方式,

結構

一個 ZipList 結構由 zlbyteszltailzllenentrieszlend 這些屬性組成,這些屬性順序連接在一起組成了 ZipList:

ZipList 結構

zlbytes 用于記錄 ZipList 占用的記憶體位元組數,在對 ZipList 進行記憶體重分配或者計算 zlend 的位置時使用,

zltail 記錄了 ZipList 表尾結點距離 ZipList 的起始地址有多少個位元組,Redis 可以通過這個屬性快速確定表尾結點的地址,

zllen 記錄了 ZipList 包含的結點數量,當這個屬性小于 UINT16_MAX(65535) 時,這個值就是 ZipList 包含的結點數量;這個屬性大于 UINT16_MAX 時,則需要遍歷整個 ZipList 才能計算得出結點數量,一個 ZipList 可以包含任意多個結點,每個結點可以保存一個位元組陣列或者一個整數值,

zlend 定義了特殊值 OxFF 用于標記 ZipList 的末端,

優點

ZipList 是一種節省記憶體的串列結構,對于普通的陣列來說,其中每個元素占用的空間大小取決于最大的元素,而 ZipList 解決了這個問題,

因此,ZipList 在設計的時候,盡量讓每個元素按照實際的內容大小存盤,所以增加了 encoding 屬性,使得程式可以根據不同的 encoding 屬性來細化存盤大小,

由于陣列每個元素都占用相同的記憶體空間,在遍歷陣列時非常方便,

而 ZipList 每個元素存盤的記憶體空間不一樣,為了解決倒序遍歷的問題,增加了 prevlen 屬性來定位上一個元素的起始位置,

缺點

ZipList 內部的資料存盤是一段連續的空間,并且沒有預留記憶體空間,在移除結點時也是立即縮容,這表示每次寫操作都會進行記憶體分配操作,

第二個缺點就是,在某種情況下,ZipList 會出現連鎖更新的問題,

連鎖更新

ZipList 存盤了 prevlen 屬性表示前一個元素的長度,如果前一個元素長度小于 254 個位元組,則 prevlen 使用 1 個位元組保存這個長度值,如果前一個結點大于 254 個位元組,則 prevlen 使用 5 個位元組保存這個長度值,

如果 ZipList 中正好存在連續多個長度介于 250~253 個位元組的結點,這時需要在 ZipList 前面插入一個大于等于 254 個位元組的新結點,后一個結點的 prevlen 需要從 1 個位元組轉換成 5 個位元組,則后一個結點也會大于等于 254 個位元組,后續的結點以此類推,將會造成這部分結點出現連續更新,

快表

Redis 在 3.2 版本之后新增了快表資料結構,它是一種以 ZipList 為結點的雙端鏈表結構,可以理解成分段的 ZipList 鏈接在一起,

快表結構

在 3.2 版本之前,Redis 使用 ZipList 或 LinkedList 來實作 List 型別,并且有一個選擇的標準:

  • 保存的所有字串元素的長度都小于 64 位元組,且保存的元素數量小于 512 個,選擇使用 ZipList
  • 否則使用 LinkedList 資料結構替代 ZipList

ZipList 要求有一段連續的記憶體空間,而使用 LinkedList 分配記憶體又會出現大量的記憶體碎片,因此 QuickList 對此做了優化,既避免出現大量的記憶體碎片,又避免一次性占用記憶體過大,

字典

字典在 Redis 中的應用非常廣泛,比如 Redis 的資料庫就是使用字典來作為底層實作的,對資料庫的增、刪、改、查操作都是構建在對字典的操作之上的,

哈希表結點

字典存盤資料的最小結構就是哈希表結點,Redis 中的哈希表結點使用 dictEntry 結構表示,每個 dictEntry 都保存著一個鍵值對:

typedef struct dictEntry {
    void *key;                  // 鍵值對的鍵
    union {                     // 鍵值對的值
        void *val;              // 可以是一個指標
        uint64_t u64;           // 可以是一個 uint64_t 整數
        int64_t s64;            // 可以是一個 int64_t 整數
    } v;

    struct dictEntry *next;     // 指向下個哈希表節點,形成鏈表
} dictEntry;

這里值得注意的就是,next 指標會指向下一個哈希表結點,而它的功能就是用于解決哈希沖突,由此可見 Redis 的哈希表解決哈希沖突的方法是鏈地址法,

哈希表

哈希表是由多個哈希表結點組成的,Redis 中自定義的哈希表結構如下:

typedef struct dictht {
    dictEntry **table;          // 哈希表陣列
    unsigned long size;         // 哈希表大小
    unsigned long sizemask;     // 哈希表大小掩碼,用于計算索引值,總是等于 size - 1
    unsigned long used;         // 該哈希表已有節點的數量
} dictht;

一般的,哈希表的物理存盤結構都是陣列,Redis 的哈希表結構也是如此,而這個結點陣列中的每個元素都是一個指向 dictEntry 結構的指標,

字典結構

Redis 為了使哈希表結構更加具有通用性,最后是在自定義的 dictht 哈希表結構外層再包一層字典結構,即是 dict 結構:

typedef struct dict {
    dictType *type;     // 型別特定函式
    void *privdata;     // 私有資料
    dictht ht[2];       // 哈希表
    int rehashidx;      // rehash 索引,當 rehash 不在進行時,值為 -1
} dict;

這里展示了另一個 dictType 的結構,其實這個結構保存了一簇用于操作特定型別鍵值對的函式,Redis 會為用途不同的字典設定不同的型別特定函式,以下是 dictType 的結構定義:

typedof struct dictType {
    unsigned int (*hashFunction)(const void *key);                          // 計算哈希值的函式
    void *(*keyDup)(void *privData, const void *key);                       // 復制鍵的函式
    void *(*valDup)(void *privData, const void *obj);                       // 復制值的函式
    int (*keyCompare)(void *privData, const void *key1, const void *key2);  // 對比鍵的函式
    void *(*keyDestructor)(void *privData, const void *key);                // 銷毀鍵的函式
    void *(*keyDestructor)(void *privData, const void *obj);                // 銷毀值的函式
} dictType;

其實 dict 結構的 type 屬性和 privdata 屬性是針對不同型別的鍵值對,為創建多型字典而設定的,其中 privData 屬性保存了需要傳給那些型別特定函式的可選引數,

需要注意一下,字典結構的 ht 屬性是一個長度為 2 的陣列,也就是說,這個字典結構存盤了兩個 dictType 結構,其中一個用于存盤實際使用的哈希表,另一個用于存盤重新哈希的臨時哈希表,

這個重新哈希還涉及到了 rehashidx 屬性,表示的是重新哈希當前的進度,

哈希演算法

當要將一個新的鍵值對添加到字典里面時,程式會先根據鍵值對的鍵計算出哈希值和索引值,然后再根據索引值,將包含新鍵值對的哈希表結點放到哈希表陣列的指定索引上,

Redis 計算哈希值和索引值的流程是:通過 dict 中的 type 屬性找到計算哈希值的函式,然后通過函式計算出對應的哈希值;確定對應的 dictht 結構之后,再根據 sizemask 和哈希值計算出索引值,

Redis 使用 MurmurHash2 演算法計算鍵的哈希值,其優點就是對于有規律的輸入值也能給出很好的隨機分布性,并且演算法的計算速度也非常快,

哈希沖突

相同的哈希值會計算出相同的索引值,這就會導致哈希沖突,

Redis 使用了鏈地址法解決哈希沖突,每一個哈希表結點都有一個 next 指標,多個沖突的哈希表結點就會使用這個 next 指標構成一個單向鏈表,這就解決了鍵沖突的問題,

這里需要注意一點,由于哈希表結點不存盤鏈表的尾結點,為了速度考慮,哈希沖突時構建的單向鏈表使用頭插法插入一個鏈表結點,

重新哈希

隨著操作不斷執行,哈希表保存的資料會逐漸增多或減少,為了讓哈希表的負載因子維持在一個合理的范圍內,Redis 會在必要的時候進行重新哈希的操作,

重新哈希指的是重新計算哈希表結點的哈希值和索引值,然后將鍵值對放到 ht 陣列的另一個哈希表中,

Redis 對哈希表進行擴展操作的兩個條件如下:

  • 服務器目前沒有正在執行 BGSAVE 命令或 BGREWRITEAOF 命令,并且哈希表的負載因子大于等于 1,
  • 服務器目前正在執行 BGSAVE 命令或 BGREWRITEAOF 命令,并且哈希表的負載因子大于等于 5,

其中負載因子 = 哈希表已保存結點數量 / 哈希表大小,

另一方面,當哈希表的負載因子小于 0.1 時,Redis 會自動開始對哈希表進行收縮操作,

Redis 做自動擴展的條件包含兩種情況的原因是,執行 BGSAVEBGREWRITEAOF 命令的是服務器的子行程,而大多數作業系統都采用寫時復制技術以優化子行程的使用效率,所以在子行程存在期間,服務器會提高執行擴展操作所需的負載因子,

漸進式重新哈希

為了避免因為重新哈希導致停止服務的情況,Redis 做重新哈希不是一次性完成的,而是分多次、漸進式地完成的,這也是 dict 結構中存在 ht 陣列的原因,

漸進式重新哈希的好處在于它采取了分而治之的方式,將重新哈希所需的計算作業均攤到對字典的每個添加、洗掉、查找和更新操作上,從而避免集中式重新哈希而帶來的龐大計算量,

整數集合

整數集合被 Redis 用于保存整數值的不重復集合,以下是整數集合的實作:

typedef struct intset {
    uint32_t encoding;      // 編碼方式
    uint32_t length;        // 集合包含的元素數量
    int8_t contents[];      // 保存元素的陣列
} intset;

其中 contents 陣列中存盤的是整數集合中的元素,各個項按照從小到大進行排列,且陣列中不包含任何重復值,

length 屬性記錄了整數集合包含的元素個數,也相當于 contents 的陣列長度,

encoding 記錄著整數集合的編碼方式,雖然 contents 的定義是 int8_t 型別,但實際上 contents 陣列存盤元素的真正型別取決于 encoding 的值,

升級

整數集合的 contents 屬性可以存盤 int16int32int64 三種型別之一的數值,如果原本只存盤了 int16 型別的 contents 陣列插入一個 int32 型別的數值,這時就涉及到整數集合的升級操作,

每當要將一個整數插入到整機集合中時,Redis 都會先判斷新元素的型別是否會比已存在的元素型別長,如果存在這種情況,整數集合需要先進行升級,才能將新元素添加到整數集合里面,具體的步驟如下:

  1. 根據新元素的型別,擴展整數集合底層陣列的空間大小,并為新元素分配空間;
  2. 將現有元素都轉換成與新元素的型別相同,并將轉換型別后的數值放置到正確的位上,并保持原陣列的順序不變;
  3. 最后改變 encoding 的值,并將 length1

整數集合的升級操作是不可逆的,一旦對陣列進行了升級,編碼就會一直保持升級后的狀態,

升級的好處

整數集合的升級策略有兩個好處,一個是提升整數集合的靈活性,另一個是盡可能地節約記憶體,

因為 C 語言是靜態型別語言,不同型別的整數值需要用不同的陣列存盤,而整數集合通過升級策略將有原本不同型別的整數添加到同一個陣列中,減少了型別錯誤的情況,

同樣的,整數集合通過使用一個陣列存盤了三種不同型別的整數,又確保升級操作只會在有需要的時候進行,這可以盡量節省記憶體,

跳表

跳表是一種有序的資料結構,它通過在每個結點中維持多個指向其他結點的指標,從而達到快速訪問結點的目的,

跳表結構

Redis 的跳表包括了兩個結構,一個是跳表結點的結構,另一個是存盤跳表結點的外部結構,

跳表結點

以下是跳表結點的結構定義:

typedef struct zskiplistNode {
    struct zskiplistLevel {             // 索引層
        struct zskiplistNode *forward;  // 前進指標
        unsigned int span;              // 跨度
    } level[];
    robj *obj;                          // 成員物件
    double score;                       // 分值
    struct zskiplistNode *backward;     // 后退指標
} zskiplistNode;

這里只是一個跳表結點的結構,概念比較多,

跳表的 zskiplistLevel 是一個陣列,陣列的長度表示結點有多少層索引,其中每個元素都包含一個指向其他結點的指標,程式可以通過這些指標加快訪問其他結點的速度,每次創建一個新的跳表結點的時候,程式都會根據冪次定律隨機生成一個介于 1 和 32 之間的值作為陣列的大小,

forward 是指每個索引層都包含指向下一個具有相同高度索引層的結點,也可以將前進指標理解成鏈表的 next 指標,從相同層級的角度上看,每一個相同層級的結點都組成了類似于鏈表的結構,

span 記錄了兩個結點之間的距離,實際上是用來計算排位的:在查找某個結點的程序中,將沿途訪問過的所有層的跨度累積起來,得到的結果就是目標結點在跳躍表的排位,

backward 用于從表尾向表頭訪問結點,對于最底層的鏈表來說,前進指標和后退指標使得這個鏈表成為一個雙向鏈表,

結點的 score 即是 Redis 的有序集合中的分值,結點的成員是一個指向 SDS 物件的指標,這個 SDS 物件存盤當前結點的值,對于相同分值的成員,Redis 會按照成員物件在字典序中的大小來進行排序,成員物件較小的結點會排在前面,而成員物件較大的結點會排在后面,

跳表

僅使用多個跳表結點就可以實作跳表,但是新增外部跳表結構可以使得程式更方便處理跳表,Redis 的跳表結構如下:

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;    // 頭節點,尾節點
    unsigned long length;                   // 節點數量
    int level;                              // 目前表內節點的最大層數
} zskiplist;

其中 head 指標和 tail 指標分別指向跳表的表頭和表尾,通過這兩個指標,Redis 定位跳表表頭結點和表尾結點的時間復雜度為 \(O(1)\)

通過記錄 length 屬性,Redis 可以在 \(O(1)\) 的時間復雜度內回傳跳表的長度,

跳表使用 level 屬性記錄了表內結點的最大層數,但這個是不包含表頭結點的層高的,

首發于「程式員翔仔」,點擊查看更多,

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/549802.html

標籤:其他

上一篇:鎖屏面試題百日百刷-kafk篇(一)

下一篇:ORACLE如何查看用戶管理備份與恢復的記錄

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more