5種Redis資料結構詳解

小云云
發布: 2023-03-21 09:02:02
原創
5630 人瀏覽過

本文我們主要和大家分享 5種Redis資料結構詳解,希望文中的案例和程式碼,能幫助大家。

        2.1.1 全域指令

            1 查看所有鍵key*

  遍歷所有鍵,而是直接取得Redis內建的鍵總數變量,時間複雜度為O(1),而keys指令會遍歷所有鍵,時間複雜度為O(n),當Redis儲存了大量鍵時,線上環境禁止使用)


            3 檢查鍵是否有  exists key 存在回傳1,不存在回傳0


     ,不存在的回傳0

            5 鍵過期expire key seconds  ttl 指令會傳回剩餘過期時間  -1 鍵沒設定過期時間-2 鍵不存在

## p. key 回傳類型,不存在返回none 


        2.1.2 資料結構與內部編碼

##          多種實現,這樣Redis會在適當的場景選擇合適的內部編碼

            每種資料結構都有兩種以上的內部編碼實現,例如list資料結構包含了linkedlist和ziplist兩種內部編碼,可透過object encoding指令查詢內部編碼

              

##   






######################' Redis這樣設計有兩個好處:第一:可以改進內部編碼,而對外的資料結構和指令沒有影響。第二 多種內部編碼實作可以在不同的場景下發揮各自的優勢。例如,ziplist比較節省內存,但是列表元素比較多的情況下,性能有所下降,這時候Redis會根據配置選項將列表類型的內部實現轉換為linkedlist#########        2.1.3 單執行緒架構#########            Redis使用了單執行緒架構與I/O多工模型來實現高效能的記憶體資料庫服務########        #######                呼叫客戶端的流程:傳送指令,執行指令,回傳結果 #########                      所有的指令在一個佇列排隊等待執行,且不存在多個指令同時執行的情況######            2 為什麼單執行緒能跑這麼快######            時間長約100奈秒,這是Redis達到每秒萬級別訪問的重要基礎######                第二,非阻塞I/O,Redis使用epoll作為I/O多路復用技術的實現,再加上Redis本身的事件處理模式將epoll中的連結、讀寫、關閉都轉換為事件,不在網路I/O上浪費過多的時間######                         第三單線程避免了線程切換和竟態產生的消耗###

                            單一執行緒帶來幾個好處:第一,以單一執行緒簡化資料結構與演算法的實現。第二,單線程避免了線程切換和竟態產生的消耗。但是每個指令的執行指令是有要求的,如果某個指令執行時間過長,就會造成其他指令的阻塞,Redis是快速執行情境的資料庫,單執行緒是理解Redis的核心          

#    2.2 字串

         Redis的字串型別是其他幾種的基礎,數值可為字串(簡單,複雜的json,xml),數位(整數,浮點),二元(圖片,音頻,視頻),最大值不能超過512MB

            

  #   


## #            1 常用指令


               


         setnx setxx同上


#                    應用情境:由於Redis是一個單一執行緒指令處理機制,如果多個客戶同時執行setnx key value,根據特性,只有一個客戶端能設定成功,可以作為分散式鎖定的一種實現方案


#                2 取得值 key 不存在返回nil

##                   4 批次取得值mget key 

#學習使用大量操作,有助於提高業務處理效率,但要注意每次批量操作所發送的命令不是無節制的,數量過多造成Redis阻塞或網絡擁塞

                5 計數incr key

                        有三種狀況使用「「問題」##  數值不是整數回傳錯誤

                          且回復為整數,而產生自增後的結果

                            鍵不存在,且依值為0自增,     還有decr(自減),incrby(自增指定數字),decrby(自減指定數字),incrbyfloat(自增浮點數)

            2 無指令

       #             2字符串長度strlen key

                3 設置並返回原值getset key value

                4 設定指定位置的字符setrange key offset value

                5 取得部分字串getrange key  start end

           8個位元組的長整型embstr 小於等於39個位元組的字串raw 大於39個位元組的字串。 Redis會根據目前值的類型和長度決定使用哪個內部編碼實現


        2.2.3 典型使用情境


                1 快取功能

            1 快取功能

               由於Redis具有支援並發的特性,所以快取通常能起到加速讀寫和降低後段壓力的作用

#                    :鍵名命名方式:業務名:物件名:id:[屬性]作為鍵名


             偽代碼實現:

rrree ##             發展提示:防作弊,依照不同維度計數,資料持久化到底層資料來源

           

##               4 定速


                 

UserInfo getUserInfo(long id){
    userRedisKey="user:info:"+id
    value=redis.get(userRedisKey);
    UserInfo userInfo;
    if(value!=null){
        userInfo=deserialize(value)
    }else{
        userInfo=mysql.get(id)
        if(userInfo!=null)
        redis.setex(userRedisKey,3600,serizelize(userInfo))
        }
登入後複製

            某網站限制一個ip位址不能在一秒鐘之內訪問超過n次也可以採用類似的思路

##    2.3 哈希

        哈希類型是指鍵值本身又是一個鍵值對結構


        2.3.1 設定值


            1 設定值」 

#            2 取得值  hget key field 


            3 刪除者 hdel 

##            5 批次設定或取得field-value  hmget key field     hmset key field value 


            6 判斷與選擇

##            8 取得所有的value hvals key

            9 對所有的field-value hget ,可以使用hscan指令,此指令會漸進式遍歷哈希類型


            10 hincrby hincrby float


##     2.3 .2 內部編碼


             內部編碼有兩種:

             者 max-ziplist-value設定時,Redis會使用ziplist作為hash的內部實現,ziplist使用更緊湊的結構實現多個元素存儲,節省內存方面比hashtable更加優秀


          表) 當hash型態無法滿足ziplist 條件時,選擇,因為hashtable的讀寫時間度為O(1)


        2.3.3.3 使用情境

##o #      #


UserInfo getUserInfo(long id){
userRedisKey="user:info:"+id;
userInfoMap=redis.hgetAll(userRedisKey);
userInfoMap userInfo;

if(userInfoMap!=null){
userInfo=transferMapToUserInfo(userInfoMap);
}else{
userInfo=mysql.get(id);
redis.hmset(userRedisKey,tranferUserInfoToMap(userInfo));
redis.expire(userRedisKey,3600);
}
return userInfo;
}
登入後複製

             哈希类型和关系型数据库两点不同:

                1 哈希类型是稀疏的,而关系型数据库是完全结构化的

                2 关系型数据库可以做复杂的查询,而Redis去模拟关系型复杂查询开发困难,维护成本高

            三种方法缓存用户信息

                1 原声字符串类型:每个属性一个键

                    

               

                优点:简单直观,每个属性都支持更新操作

                缺点:占用过多的键,内存占用量较大,同时用户信息内聚性比较差,所以一般不会在生产环境用

               2 序列化字符串类型:将用户信息序列化后用一个键保存

        

                优点:简化编程,如果合理的使用序列化可以提高内存的使用效率

                缺点:序列化和反序列化有一定的开销,同时每次更新属性,都需要把数据取出来反序列化,更新后再序列化到Redis中

                3 哈希类型:每个用户属性使用一对field-value,但是只用一个键保存

                优点:简单直观,如果使用合理,可以减少内存空间的使用

                缺点:要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable会消耗更多的内存

    2.4 列表

        列表类型用来存储多个有序的字符串,一个列表最多存储2的32次方-1个元素,列表是一种比较灵活的数据结构,它可以灵活的充当栈和队列的角色,在实际开发上有很多应用场景

        列表有两个特点:第一、列表中的元素是有序的,这就意味着可以通过索引下标获取某个元素或者某个范围内的元素列表。第二、列表中的元素可以是重复的

        2.4.1 命令

            1 添加操作

                 1.1 从右边往左插入元素 rpush key value

                 1.2 从左往右插入元素 lpush key value

                 1.3 向某个元素前或者后插入元素 linsert key before|after pivot value

                    

            2 查找

                1 获取指定范围内的元素列表 lrange key start end            

               地,這個和許多程式語言不包含end不太相同

                2 取得清單指定索引下標的元素lindex key index

##            3 移除

                1  彈出rpop key

                3 刪除指定元素lr  4 修改

                修改指定指標下標的元素lset key index newValue

            5 阻塞操作brpop blpop key timeout


         0,客戶端則阻塞等下去,如果增加了數據,客戶端立刻回傳

                2 清單不為空白:客戶端立即回傳#c

        2.4.2 內部編碼

               #   (壓縮列表):當列表元素個數< list-max-ziplist-entries,同時list-max-ziplist-value(64位元組),Redis會選用清單的內部實作來減少記憶體的使用

           無法滿足ziplist的條件時,Redis會使用linkedlist作為清單的內部實作

        2.4.3 使用情境

          #            Redis的lpush+brpop指令組合即可實現阻塞佇列


                          


                        兩個問題:第一,如果每次分頁獲取的文章個數較多,需要執行多次hgetall操作,此時考慮使用pipeline批量獲取,或者考慮將文章資料序列化為字符串類型,使用mget批量獲取。第二,分頁取得文章清單時,lrange指令在清單兩端表現較好,但若清單較大,取得清單中間範圍元素的效能會變差,此時可以考慮二級分割


                     

                     +ltrim=Capped Collection(有限集合)

                        lpush+brpop=Message Queue(訊息佇列)

# 有重複元素,並且集合中元素是無序的


        2.5.1 命令


            1 集合內操作


                1.1 添加元素sadd key element 


                1.2 刪除元素srem key element


   #. #                1.4 判斷元素是否在集合中sismember key element


                1.5 隨機從集合回傳指定數量元素srandmember key 


##                1.7取得所有元素smembers key


            2 集合間操作


                   2 求多個集合的並集suinon key..


                3 求多集合的差集sdiff key ..

#保存 

                     sinterstore destination key 


  


#                     suionstore destionation key


     

##        2.5.2 內部編碼

            為集合型的內部有兩種:

# 都是整數且元素個數小於set-max-intset-entries配置(預設為512個)時,Redis會選用intset來作為集合內部的實現,從而減少內存的使用


##             雜湊表) 當集合類型無法滿足intset的條件時,Redis會使用hashtable作為集合的內部實現


        2.5.3 使用場景

           是標籤。

             1 為使用者新增標籤

              2 為標籤新增使用者 


#                sadd tag1:users user:1 user:3


           命令

##         與「未建立」指令


            3 刪除使用者中的標籤


             #  標籤下的使用者

                srem tag1:users user:1


#

            5 計算使用者共同感興趣的標籤

               =Tagging(標籤) spop/srandmember =Random item(產生隨機數,如抽獎)

spop/srandmember=Random item(產生隨機數,如抽獎) sadd+sinter=Social Graph(社交需求)

    2.6 有序集合

        有序集合就是在集合之上加了個score作為排序的依據 

        

        2.6.1 指令

            1 集合內

  

nx xx   ch 返回此操作後,有序集合元素和分數發生變化的個數,incr:對score做增加

                有序集合相比集合提供了排序字段,但是也產生排序字段,但是也產生了排序字段,但是也產生排序了代價,zadd的時間複雜度為O(log(n)),sadd的時間複雜度為O(1)

                2 計算成員個數

scard key

                3 計算某成員的分數zscore key member

                 5 刪除成員zrem key member

                6 增加成員的分數zincrby key increment member

      #               8 回復指定分數範圍的成員zrangebysore key min max 


                9 傳回指定分數範圍成員個數zcount key min 

#.元素zremrangebyrank key start end


                11 刪除指定分數範圍的成員zremrangebyscore key min max


    #         1 交集zinterstore destination numkeys key 


                2 並收集zunionstore destionation numkeys key


     有序集合類型的內部編碼有兩種:


                      地來作為有序集合的內部實現,ziplist可以有效的減少內存的使用


                          時ziplist的讀寫效率會下降

        2.6.3 使用場景


     例如影片網站需要對使用者上傳的影片做排行榜榜

                              crby user:ranking:2016_03_15 mike 1

                    2 取消使用者讚數

                        zrem user:rank:2016_03_15 mike 取得最多讚數的十個使用者

                        zrevrangebyrank user:ranking:2016_03_15 0 9

                    4 顯示使用者資訊與使用者分數

      保存在哈希類型中,至於用戶的分數和排名可用zcore和zrank兩個功能          

              ##  ##        2.7.1 單一鍵管理

            1 鍵重命名rename key newkey

         -1 鍵沒有設定過期時間-2 鍵不存在

                expire key seconds:鍵在seconds秒後過期

##  st 100 月過期


                1 若expire key的鍵不存在,且回傳結果為0


           

#          
#                3 persist 指令可以將鍵的過期時間清除


          

           #1

                5 Redis不支援二級資料結構內部元素的過期功能,例如無法這清單類型的一個元素做過時間設定
 否但原子執行,同時減少了網路通訊的時間


            4 遷移鍵


          的方法,它們的實現方式以及使用場景不太相同


                    1 move 用於在Redis內部進行資料遷移# restore 實作在不同的Redis實例之間進行資料遷移的功能,此遷移分兩步驟


                        1 在源源  

                為    

                           Redis提供了兩個指令遍歷所有的鍵分別有任意字元

                       .代表與字元中配對一個字元

                        [] 代表為符合一個字元

    號,問號需轉義

                     且容易造成阻塞

                    2為漸進式遍歷

    

                        scan則以想像為只掃描字典中的一部分鍵,直到將字典所有鍵遍歷完畢


             對應的指令還有hsan、sscan、zcan


      有增刪的時候,新來的鍵無法保證遍歷到


        2.7.3 資料庫管理

       #   

##       #  2 flushdb/flushall 用於清除資料庫資料多的時候會出現阻塞

    2.8 本章終點回顧

  相關建議:

Redis 資料結構

以上是5種Redis資料結構詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!