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

歡迎訪問 生活随笔!

生活随笔

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

数据库

Redis数据结构以及对应存储策略

發布時間:2023/12/4 数据库 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis数据结构以及对应存储策略 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

redis數據結構:

  • String 可以是字符串也可以是數字,以及浮點數
  • List,一個鏈表,鏈表上每一個節點都包含一個字符串
  • set 包含字符串的無序手機其,特點是每一個字符都是唯一的
  • hash,包含鍵值對的無序散列,類似map
  • ZSet,字符串成員,在set的基礎上是順序的,元素的順序由分值來決定
  • redis的發布與訂閱的特性(重點):
    • subscribe channel命令 訂閱給定的一個或者多個頻道
    • pushlish channel message 給指定頻道發送消息,
    • 通過這兩個命令redis可以實現發布與訂閱功能
  • redis的基本事務功能
    • redis通過multi和exec命令來實現事務的特性,在執行multi命令之后,redis會將這個客戶端之后發送的所有命令存儲在一個隊列中,直到接受到exec命令為止。然后會在不被打斷的情況下執行這些操作
  • redis鍵過期時間:使用expiration設置key存活的時間,之后自動刪除
重要的數據結構
  • hyperLogLog:基數計算概念:通常用來統計一個集合中不重復元素個數,比如用來統計網站的UV,或者網站搜索關鍵字的數量。最簡單的辦法是用給一個集合做統計,判斷新詞是否存在,然后添加存在兩個問題,數據量會變很大,判斷成本會變得很高。bitMap存儲1 億個數據大概要12M內存,redis中HyperLogLog(HLL)中只需要1K內存就能做到
    • hyperLogLog原理(簡析):將需要統計的數據進行HASH,得到每個數據對應二進制串,統計得到的二進制串中從低位開始第一次出現1的情況并且進行統計,統計每個key的這種1 的位置,讓后用概率和統計的方法推到出統計和數據量之間的關系,HyperLogLog核心在于集合中每個實體對應的Hash串,通過這種統計來預估整體的量,可以大大減少內存的耗費,所以這種方式并沒有存儲所有的樣本,而是通過樣本估算的方式推算出總體大小。(數學原理 伯努力分布)
  • GEO redis3.2中的新特性用來存儲和獲取經緯度,以及地理位置,還有位置距離計算等內容 如下操作
//設置信息 GEOADD beijing 113.2099647 23.593675 五道口 //GEOADD 地址 經度 緯度 地區 GEOADD beijing 113.2099643 23.593674 上地 //獲取信息 GEOPOS beijing 上地 //獲取指定信息地點 900m范圍的地點 GEORADIUS beijing 113.2099647 23.593675 900 m
  • redis modules:redis4.0 曾加了自定義模塊的開發,類似于3.X版本中lua腳本的兼容,但是lua有一定學習量,在4.0中提供了一系列模塊源碼: https://github.com/RedisLabsModules/redex ,可以通過命令將對應的模塊代碼導入到redis中,就可以使用對應自定義命令
SADD admins Alice Bob xiaorui.cc
  • BloomFilter:主要功能是用來做去重,我們可以用來對訪問UV和購買UV的實時去重,具體原理如下:
    • BloomFilter過濾器會將key做一次Hash,將hash后得到的int分布到一個大的Bit數組中對應的位,判斷一個Key是否存在,只要看Hash對應的bit數組位置是否是1,1則被占用,0不被占用
    • 而且redis2.0 以后就支持bigMap的操作,以及Bit操作中的AND,OR,NOT,XOR操作,bitMap支持232 大小,也就是512M,下標最大232-1,可以存2億左右數據
  • Redis Search:基于redis的搜索插件,可以用來做全局key值的模糊查詢,并且可以兼容一部分通配符
  • Redis-ML :用來做機器學習的

redis數據安全與性能保障

  • redis提供兩種不同持久化方式來將數據存儲到硬盤:

    • 快照模式(RDB)可以將存在某一個時間點上所有數據寫入硬盤

      • RDB模式通過配置信息來啟動,并且設置觸發的配置,比如save 60 10000 在最近一次快照算起,60秒以內有10000次寫操作,自動執行一次BGSAVE命令做備份
      • 快照生成一個rdb文件,可以拷貝,但是在心快照創建完畢之前,redis,系統,硬件有一個出現問題,那么redis將會丟失最近一次快照之后的所有寫入數據。
      • 可以手動創建快照:通過BGSAVE命令,redis會調用fork來創建一個子進程,他來完成寫入,父子進程共享內存,直到父進程有寫入操作的時候共享結束
      • 只適合哪些可以容忍少部分數據丟失的業務場景
      • rdb方式需要找到save配置的點,因為如果過于頻繁會浪費資源,過于稀少可能丟失大量數據,我們一般做法是在測試機器上盡量模擬線上環境
      • 執行BGSAVE會使redis停頓一定時間取決于系統以及硬件
    • 追加文件模式(AOF),在執行寫命令時候將這條命令復制到硬盤

      • AOF方式也可以通過配置方式打開,他會將所有寫命令追加到aof文件末尾,redis只需要執行一次aof文件就可以恢復所有記錄。
      • 配置寫入頻率:always:每個寫入都同步aof文件到硬盤,效率極低。everysec:每一秒同步一次 no:讓操作系統來決定何時同步。
      • 一般使用everysec,每秒執行一次和不適用任何持久化的性能比差不多,這樣可以保證做多丟失一秒的數據
      • aof文件可能會變得很大甚至沾滿硬盤,這時候redis重啟需要執行AOF文件中所有命令這個執行時間會很長
      • 可以通過向redis發送BGREWRITEAOF命令來移除榮譽的命令,來重寫aof文件,但是如果文件太大,刪除一個十幾G的文件redis可能會處于掛起狀態數秒
    • 方式可以同時使用也可以單獨,也可以不用

redis過期策略
  • 惰性刪除:當讀/寫一個已經過期的Key的時候,會發生惰性刪除策略,直接刪除這個Key,很明顯,太被動了
  • 定期刪除:由于惰性刪除策略無法保證冷數據被幾及時刪除,所以redis會定期主動淘汰一批已經過期的Key
  • 主動刪除:當前已有的數據內存超過MaxMemory的時候,觸發自動清策略,該策略由啟動參數的配置決定
    • volatile-lru:從已經設置過期時間的數據集合中通過LRU算法淘汰數據,3.0以前的默認策略:
    • volatile-ttl:從過期數據集合中挑選過期時間最小的數據刪掉
    • volatile-random:從已過期集合中所見刪除數據
    • allkey-lru:從所有數據聚合中通過lru刪掉
    • allkey-random:從所有數據集合中隨機刪除
    • noenviction:禁止從內存中刪除數據 3.0默認策略
    • redis過期策略只在主庫中進行所有很容易在從庫中讀到臟數據:以下方式避免
      • 通過sca命令掃庫,相當于訪問這個key,充分發揮惰性刪除,但是確定在于會在掃庫的時候給數據庫帶來一定壓力,所有需要找好時間點去執行。
      • 升級redis到3.0版本,在3.0 以后的版本中修復了這個問題,可以在源碼中看到,曾加了對key值的主從庫的判斷,然后key為空,擇返回null
    redis緩存遇到的問題
    • 緩存穿透:一般緩存系統按照key去緩存查詢,value不存在,就去后端系統查找,如果key對應的value不存在,并且這個key訪問量巨大,這樣會給后端DB造成很大的壓力,這就叫緩存穿透:

      • 解決方案一:對查詢結果為空的情況也進行緩存一個null,之后如果insert了之后在清理這個null的緩存
      • 對一定不存在的key進行過濾,放到一個足夠大的bitMap中,不存在數據會被這個bitMap攔截
    • 緩存雪崩:如果我們設置緩存時候在同一個時刻過期,導致某一個時刻緩存幾乎失效,請求都裝法DB,DB瞬時壓力過大雪崩

      • 解決方案:如果需要集中社會緩存過期時間,那么我們一般會在緩存失效時間的計算上加一個隨機數,這樣緩存到期時間就可以分散開
    • 緩存擊穿:對于設置了過期時間的key,如果這些key在某些時間點被高超并發訪問,這個時候必須考慮唄擊穿的問題,和雪崩區別在于這是某一個key,正好過期的時候高并發訪問一個key

      • 解決方案一:使用互斥鎖,mutex key,就是在緩存失效的時候并不立馬去load db,而是先使用緩存工具中某一些帶成功操作返回值的操作,比如 redis的setNx實現的互斥鎖,他去set一個mutex key,當操作返回成功之后在去load db并且設置到緩存中,如果返回失敗,重試get方法,這樣就可以只有一個請求到DB層,代碼如下
      public String get(String key) {String value = redis.get(key);if (value == null) { //代表緩存值過期//設置3min的超時,防止del操作失敗的時候,下次緩存過期一直不能load dbif (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表設置成功value = db.get(key);redis.set(key, value, expire_secs);redis.del(key_mutex);} else { //這個時候代表同時候的其他線程已經load db并回設到緩存了,這時候重試獲取緩存值即可sleep(50);get(key); //重試}} else {return value;}}
      • 解決方案二:可以設置無過期時間,做邏輯過期,在redis上不做過期的設置,就不會出現這種情況,但是在value中設置一個過期的時間,在獲取value之后判斷是否過期,過期擇重新load到cache,這樣可能會有其他線程讀到過期的數據,但是應該影響不大
    redis 分布式鎖
    • redis中有一個命令 setNx(key存在時候設置值),成功返回1,可以用setNx來爭奪鎖,在通過expire來設置過期時間防止忘記釋放,也可以直接通過redis.setnx(key_mutex, 1, 3 * 60),同時設置值與時間,如下jedisclient源碼:
    while(true) {result = this.jedisCluster.set(lockKey, lockKey, "NX", "EX", 30L);if("OK".equals(result)) {return true;}try {Thread.sleep(1000L);} catch (InterruptedException var4) {;}}
    redis可能有的問題
    • redis中有1億個key,其中10萬個是一樣的前綴開頭,如何全部找出來:
      • 可以用keys命令,因為redis是單線程的,如果用keys會造成服務停頓
      • 用scan遍歷所有key,可以無阻塞的提取指定模式的列表,但是可能會有重復,時間更長
    • Redis做異步消息隊列:
      • 用list結構可以,通過repush生產消息,lpop消費消息,沒有消息可以sleep之后再做,或者用blpop命令,他會阻塞直到獲取消息。
      • 可以用pub/sub命令做消息隊列并且可以實現一次消息消費多次 1:N
      • 延遲隊列可以用sort命令對一個set進行排序,排期的對象是時間戳,這樣我們可以通過邏輯去匹配一定時間之前的消息。
    • 大量的key需要設置同一時間過期一般需要注意緩存雪崩效應:
      • 所有值統一時刻過期,導致直接到DB查詢,可以通過隨機值,分散過期的時間
    • redis如何做數據持久化:
      • rdb模式我們可以通過bgsave方式主動去觸發,同時也做aof做持久化,bgsave會持續一段時間,不夠實時性,如果機器有問題可能會丟比較多的數據,aof是記錄寫命令,這個丟失的數據比較少,在重啟的時候,會用bgsave的文件進行數據恢復,然后在用aof來恢復沒有備份到文件中的數據,這樣做到最小丟失。
      • rdb原理如上:redis通過fork出一個子進程來做bgsave操作,父子進程共享內存直到父進程有寫操作,共享結束。
    • redis同步機制:
      • redis一般是主從同步,從從同步,master在同步時候,先bgsave一次,期間所有寫入都在緩存buffer,然后將rdb文件同步到從節點,從節點loader到內存,通知主節點將緩存中的寫入同步。
    redis集群
    • redis3.0 的新特性就是自帶集群功能,3.0 下的集群沒有中心節點,RedisCluster 將所有的key映射到16385個slot中,每一個redis實例負責一部分最少三個實例一個集群,業務程序通過任務一個redisCluster都可以訪問所有的數據,如果數據不再這個節點,那么這個節點會引導客戶端去對應節點獲取信息,redisCluster的管理實通過節點之間的通訊完成,定期交互,定期更新
    • 每一個節點都可以配置一個從節點,集群中三個redisCluster某個掛了,從節點將頂替他的位置,,主從復制的功能 和單機的時候一直,所以叫他基于主從配置的redis集群。

    總結

    以上是生活随笔為你收集整理的Redis数据结构以及对应存储策略的全部內容,希望文章能夠幫你解決所遇到的問題。

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