日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis 10亿数据量只需要100MB内存,为什么这么牛?

發布時間:2025/3/21 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis 10亿数据量只需要100MB内存,为什么这么牛? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:java架構設計 ?
來源:toutiao.com/i6767642839267410445

本文主要和大家分享一下redis的高級特性:bit位操作。

力求讓大家徹底學會使用redis的bit位操作并掌握其底層實現原理!主要包含以下內容:

  • redis位操作命令示例

  • 底層數據結構分析

  • 為什么他的算法時間復雜度是O(1)?

  • 10億數據量需要多大的存儲空間?

  • redis位操作適合哪些應用場景?

  • 本文redis試驗代碼基于如下環境:

    操作系統:Mac OS 64位

    版本:Redis 5.0.7 64 bit

    運行模式:standalone mode

    redis位操作

    reids位操作也叫位數組操作、bitmap,它提供了SETBIT、GETBIT、BITCOUNT、BITTOP四個命令用于操作二進制位數組。

    先來看一波基本操作示例:

    SETBIT

    語法:SETBIT key offset value

    即:命令 key 偏移量 0/1

    setbit命令用于寫入位數組指定偏移量的二進制位設置值,偏移量從0開始計數,且只允許寫入1或者0,如果寫入非0和1的值則寫入失敗:

    GETBIT

    語法:GETBIT key offset

    即:命令 key 偏移量

    gitbit命令用于獲取位數組指定偏移量上的二進制值:

    BITCOUNT

    語法:BITCOUNT key

    即:命令 key

    bitcount命令用于獲取指定key的位數組中值為1的二進制位的數量,之前我們寫入了偏移量0的值為1,偏移量10 的值為1,偏移量8的值為0:

    BITOP

    語法:BITOP operation destkey key [key…]

    即:命令 操作 結果目標key key1 key2 …

    bitop命令可以對多個位數組的key進行and(按位與)、or(按位或)、xor(按位異或)運算,并將運算結果設置到destkey中:

    底層數據結構分析

    SDS是redis中的一種數據結構,叫做簡單動態字符串(Simple Dynamic String),并且它是一種二進制安全的,在大多數的情況下redis中的字符串都用SDS來存儲。

    SDS的數據結構:

    struct?sdshdr?{#記錄buff數組中已使用字節的數量#也是SDS所保存字符串的長度int?len;#記錄buff數組中未使用字節的數量int?free;#字節數組,字符串就存儲在這個數組里char?buff\[\]; }

    數據存儲示例:

    圖片來源《redis設計與實現》

    SDS的優點:

  • 時間復雜度為O(1)

  • 杜絕緩沖區溢出

  • 減少修改字符串長度時候所需的內存重分配次數

  • 二進制安全的API操作

  • 兼容部分C字符串函數

  • 關于SDS的詳細介紹請大家參閱《redis設計與實現》一文。

    redis中的位數組采用的是String字符串數據格式來存儲,而字符串對象使用的正是上文說的SDS簡單動態字符串數據結構。

    圖片來源《redis設計與實現》

    大家都知道的是一個字節用的是8個二進制位來存儲的,也就是8個0或者1,即一個字節可以存儲十進制0~127的數字,也即包含了所有的數字、英文大小寫字母以及標點符號。

    1Byte=8bit

    1KB=1024Byte

    1MB=1024KB

    1GB=1024MB

    位數組在redis存儲世界里,每一個字節也是8位,初始都是:

    0?0?0?0?0?0?0?0

    而位操作就是在對應的offset偏移量上設置0或者1,比如將第3位設置為1,即:

    0?0?0?0?1?0?0?0 #對應redis操作即: setbit?key?3?1

    在此基礎上,如果要在偏移量為13的位置設置1,即:

    setbit?key?13?1 #對應redis中的存儲為: 0?0?1?0?|?0?0?0?0?|?0?0?0?0?|?1?0?0?0

    時間復雜度

    GETBIT命令時間復雜度O(1)

    STEBIT命令時間復雜度O(1)

    BITCOUNT命令時間復雜度O(n)

    BITOP命令時間復雜度O(n)、O(n2)

    我們來看GETBIT以及SETBIT命令的時間復雜度為什么是O(1),當我們執行一個SETBIT key 10086 1的值的時候,reids的計算方式如下:

    獲取到要寫入位數組中的哪個字節:10086÷8=1260,需要寫入到位數組的下標1260的字節

    獲取要寫入到這個字節的第幾位:10086 mod 8 = 6,需要寫入到這個字節的下標為6即第7位上去。

    通過這兩種計算方式大家可以清晰的看到,位操作的GETBIT和SETBIT都是常量計算,因此它的時間復雜度為O(1)。

    而BITCOUNT命令需要對整個位數組的所有元素進行遍歷算出值為1的有多少個,當然redis對于大數據了的bit執行bitcount命令會有一整套復雜的優化的算法,但是核心思路還是這個意思,無非是減少部分遍歷查詢次數。比如以128位為一次遍歷,那么他的遍歷次數就是所有的位數除以128。

    BITTOP命令則是根據不同的操作有不同的執行方式。比如AND操作,則需要查看位值為1的即可。

    存儲空間計算

    根據上面的介紹,相信大家已經知道了基于redis的位數組數據結構存儲的數據占用內存大小是怎么計算的了。比如有100億的數據,那么它需要的字節數組:

    1000000000÷8÷1024÷1024≈119.21MB

    也就是存儲10億的數據只需要119MB左右的內存空間,這對于現在動輒16G、32G集群版的redis,完全沒有問題。

    需要注意的是,如果你的數據量不大,那就不要把起始偏移量搞的很大,這樣也是占空間的,比如我們只需要存儲幾百條數據,但是其中的偏移量卻很大,這就會造成了很大的內存空間浪費。

    應用場景

    實際項目開發中有很多業務都適合采用redis的bit來實現。

    用戶簽到場景

    每天的日期字符串作為一個key,用戶Id作為offset,統計每天用戶的簽到情況,總的用戶簽到數

    活躍用戶數統計

    用戶日活、月活、留存率等均可以用redis位數組來存儲,還是以每天的日期作為key,用戶活躍了就寫入offset為用戶id的位值1。

    同理月活也是如此。

    用戶是否在線以及總在線人數統計

    同樣是使用一個位數組,用戶的id映射偏移量,在線標識為1,下線標識為0。即可實現用戶上下線查詢和總在線人數的統計

    APP內用戶的全局消息提示小紅點

    現在大多數的APP里都有站內信的功能,當有消息的時候,則提示一個小紅點,代表用戶有新的消息。

    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的Redis 10亿数据量只需要100MB内存,为什么这么牛?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。