Redis學習——數據結構上

1、經常使用的全局命令redis

        一、查看全部的鍵: KEYS *數據庫

KEYS pattern:查找全部符合給定模式 pattern 的 key 。編程

KEYS 的速度很是快,但在一個大的數據庫中使用它仍然可能形成性能問題,若是你須要從一個數據集中查找特定的 key ,你最好仍是用 Redis 的集合結構(set)來代替。數組

時間複雜度:O(N), N 爲數據庫中 key 的數量。緩存

二、鍵總數:dbsize(返回當前數據庫中鍵的總數)安全

三、檢查建是否存在 exists key數據結構

四、刪除鍵:del key[...]:del是一個通用命令,不管什麼數據結構類型,del命令均可以將他刪除。app

同時del命令支持刪除多個鍵del a b c(同事刪除a b c 三個鍵)負載均衡

五、鍵過時:expire key seconds運維

ttl命令會返回鍵的剩餘過時時間,它有三種返回值:大於0的整數(鍵剩餘的過時時間),-1(鍵沒設置過時時間),-2:鍵不存在

六、鍵的數據結構類型:type key

2、數據結構和內部編碼

redis對外的數據結構有五種:string(字符串)、hash(哈希)、list(列表)、set(集合)、zset(有序集合)

這些只是redis對外的數據結構,實際上每種數據結構都有本身的底層的內部編碼實現,並且是多種實現。例如LIST包含了linklist和ziplist兩種內部編碼。用object encoding key 能查詢內部編碼

1)、字符串

字符串類型是redis最基礎的數據結構。字符串的值不能超過512M.

字符串經常使用命令

一、設置值: set key value

set rdb 123 :設置一個鍵rdb,值爲123

set rdb 123 ex 10:設置一個鍵rdb,值爲123,過時時間爲10秒

set rdb 123 px 10:設置一個鍵rdb,值爲123,過時時間爲10毫秒

setex rdb 10 123: 設置一個鍵rdb,值爲123,過時時間爲10秒

set rdb 1 xx:將鍵rdb的值更新爲1

set rdb 123 nx:設置一個鍵rdb,值爲123

setnx rdb 123:設置一個鍵rdb,值爲123

說明:setex和setnx兩個命令做用和ex和nx選項是同樣的。

  setnx和set的區別:因爲redis的單線程命令處理機制,若是有多個客戶端同時執行setnx key value,根據setnx的特性只有一個客戶端能設置成功,setnx能夠做爲分佈式鎖的一種

實現方案,Redis官方給出了使用setnx實現分佈式鎖的方法:http://redis.io/topics/distlock。

二、獲取值:get key

若是獲取的鍵不存在,則返回nil(空)

三、批量設置值

mset key value [key value]

mset a 1 b 2 c 3 d 4:設置了4個鍵值對

四、批量獲取值

mget key [key ...]

mget a b c d

    批量操做命令能夠有效提升開發效率

五、計數

incr命令用於對值作自增操做,返回結果分爲三種狀況

一、值不是整數,返回錯誤

二、值是整數,返回自增後的結果

三、鍵不存在,按照值爲0自增,返回結果爲1

不經常使用的命令:

一、追加值 append key value(append能夠向字符串尾部追加值)

二、字符串長度  strlen key(每一箇中文佔3個字節)

三、設置並返回原值(getset和set同樣會設置值,可是不一樣的是,它同時會返回鍵原來的值)

四、設置指定位置的字符 setrange key offeset value

set redis pest

setrange redis 0 b :將pest變成best

五、獲取部分字符串 getrange key start end

set redis best

getrange redis 0 1:返回be

內部編碼:字符串類型的內部編碼有3種

.int:8個字節的長整型。

·embstr:小於等於39個字節的字符串。

·raw:大於39個字節的字符串。

        (Redis會根據當前值的類型和長度決定使用哪一種內部編碼實現。)

redis字符串的典型使用場景:

一、緩存功能

與MySQL等關係型數據庫不一樣的是,Redis沒有命令空間,並且也沒有對鍵名有強制要求(除了不能使用一些特殊字符)。但設計合理的鍵名,有利於防止鍵衝突和項目的可維護性,

比較推薦的方式是使用「業務名:對象名:id:[屬性]」做爲鍵名(也能夠不是分號)。

二、計數功能

許多應用都會使用Redis做爲計數的基礎工具,它能夠實現快速計數、查詢緩存的功能,同時數據能夠異步落地到其餘數據源。

三、共享Session

可使用Redis將用戶的Session進行集中管理,在這種模式下只要保證Redis是高可用和擴展性的,每次用戶更新或者查詢登陸信息都直接從Redis中集中獲取。

四、限速

不少應用出於安全的考慮,會在每次進行登陸時,讓用戶輸入手機驗證碼,從而肯定是不是用戶本人。可是爲了短信接口不被頻繁訪問,會限制用戶每分鐘獲取驗證碼的頻率,例如一分鐘不能超過5次。

 

二、哈希

幾乎全部的編程語言都提供了哈希(hash)類型,它們的叫法多是哈希、字典、關聯數組。在Redis中,哈希類型是指鍵值自己又是一個鍵值對結構,形如value={{field1,value1},...{fieldN,valueN}}

注意(哈希類型中的映射關係叫做field-value,注意這裏的value是指field對應的值,不是鍵對應的值,請注意value在不一樣上下文的做用)

經常使用命令:

一、設置值 hset key field value

hset user:1 name tom:設置鍵爲user:1 ,filed爲name,value爲tom。

二、獲取值 hget key field

hget user:1 name  :返回tom

三、刪除field hdel key field [field ...]

hdel user:1 name

四、計算field個數

hlen key

五、批量設置或獲取field-value

hmget key field [field ...]

hmset key field value [field value ...]

六、判斷field是否存在 hexists key field

七、獲取全部field: hkeys key

八、獲取全部value:hvals key

九、獲取全部的field-value:hgetall key

(注意:在使用hgetall時,若是哈希元素個數比較多,會存在阻塞Redis的可能。若是開發人員只須要獲取部分field,可使用hmget,若是必定要獲取所有field-value,可使用hscan命令,該命令會漸進式遍歷哈希類型)

十、hincrby hincrbyfloat

十一、計算value的字符串長度 hstrlen key field

內部編碼(哈希類型的內部編碼有兩種)

·ziplist(壓縮列表):當哈希類型元素個數小於hash-max-ziplist-entries配置(默認512個)、同時全部值都小於hash-max-ziplist-value配置(默認64字節)時,Redis會使用ziplist做爲哈希的內部實現,ziplist使用更加緊湊的結構實現多個元素的連續存儲,因此在節省內存方面比hashtable更加優秀

·hashtable(哈希表):當哈希類型沒法知足ziplist的條件時,Redis會使用hashtable做爲哈希的內部實現,由於此時ziplist的讀寫效率會降低,而hashtable的讀寫時間複雜度爲O(1)。

使用場景:一、存儲關係數據庫數據

相比於使用字符串序列化緩存用戶信息,哈希類型變得更加直觀,而且在更新操做上會更加便捷。能夠將每一個用戶的id定義爲鍵後綴,多對field-value對應每一個用戶的屬性

(可是須要注意的是哈希類型和關係型數據庫有兩點不一樣之處:·哈希類型是稀疏的,而關係型數據庫是徹底結構化的,例如哈希類型

每一個鍵能夠有不一樣的field,而關係型數據庫一旦添加新的列,全部行都要爲其設置值(即便爲NULL)

·關係型數據庫能夠作複雜的關係查詢,而Redis去模擬關係型複雜查詢開發困難,維護成本高。

(比較說明名:到目前爲止,咱們已經可以用三種方法緩存用戶信息,下面給出三種方案的實現方法和優缺點分析。

一、原生字符串類型:每一個屬性一個鍵。

set user:1:name tom

set user:1:age 23

set user:1:city beijing

優勢:簡單直觀,每一個屬性都支持更新操做。

缺點:佔用過多的鍵,內存佔用量較大,同時用戶信息內聚性比較差,因此此種方案通常不會在生產環境使用。

二、序列化字符串類型:將用戶信息序列化後用一個鍵保存。

set user:1 serialize(userInfo)

優勢:簡化編程,若是合理的使用序列化能夠提升內存的使用效率。

缺點:序列化和反序列化有必定的開銷,同時每次更新屬性都須要把所有數據取出進行反序列化,更新後再序列化到Redis中。

三、哈希類型:每一個用戶屬性使用一對field-value,可是隻用一個鍵保存。

hmset user:1 name tomage 23 city beijing

優勢:簡單直觀,若是使用合理能夠減小內存空間的使用。

缺點:要控制哈希在ziplist和hashtable兩種內部編碼的轉換,hashtable會消耗更多內存。

三、列表List(列表(list)類型是用來存儲多個有序的字符串)

在Redis中,能夠對列表兩端插入(push)和彈出(pop),還能夠獲取指定範圍的元素列表、獲取指定索引下標的元素等。列表是一種比較靈活的數據結構,它能夠充當棧和隊列的角色,在實際開發上有不少應用場景。

一、列表的兩個特色

.列表中的元素是有序的

.列表中的元素能夠是重複的

二、命令

一、添加操做

·從右邊插入元素 rpush key value [value ...](lrange 0 -1命令能夠從左到右獲取列表的全部元素)

·從左邊插入元素 lpush key value [value ...]

·向某個元素前或者後插入元素  linsert key before|after pivot value (linsert命令會從列表中找到等於pivot的元素,在其前(before)或者後(after)插入一個新的元素value)

二、查找

·獲取指定範圍內的元素列表 lrange key start end (lrange操做會獲取列表指定索引範圍全部的元素)

索引下標有兩個特色:一、索引下標從左到右分別是0到N-1,可是從右到左分別是-1到-N

    二、lrange中的end選項包含了自身

        ·獲取列表指定索引下標的元素 lindex key index:例如 lindex listkey -1

·獲取列表長度 llen key

三、刪除

·從列表左側彈出元素 lpop key

·從列表右側彈出 rpop key

·刪除指定元素 lrem key count value 

lrem命令會從列表中找到等於value的元素進行刪除,根據count的不一樣分爲三種狀況:

·count>0,從左到右,刪除最多count個元素。

·count<0,從右到左,刪除最多count絕對值個元素。

·count=0,刪除全部。

·按照索引範圍修剪列表 ltrim key start end

ltrim listkey 1 3 (只保留列表listkey第2個到第4個元素)

四、修改

·修改指定索引下標的元素: lset key index newValue

五、阻塞操做

·阻塞式彈出以下:blpop key [key ...] timeout和brpop key [key ...] timeout

(blpop和brpop是lpop和rpop的阻塞版本,它們除了彈出方向不一樣,使用方法基本相同,因此下面以brpop命令進行說明,

brpop命令包含兩個參數:·key[key...]:多個列表的鍵。

       ·timeout:阻塞時間(單位:秒)。

1)列表爲空:若是timeout=3,那麼客戶端要等到3秒後返回,若是timeout=0,那麼客戶端一直阻塞等下去

若是此期間添加了數據element1,客戶端當即返回

2)列表不爲空:客戶端會當即返回。

在使用brpop時,有兩點須要注意

第一點,若是是多個鍵,那麼brpop會從左至右遍歷鍵,一旦有一個鍵能彈出元素,客戶端當即返回:

第二點,若是多個客戶端對同一個鍵執行brpop,那麼最早執行brpop命令的客戶端能夠獲取到彈出的值

 

三、內部編碼

列表類型的內部編碼有兩種。

·ziplist(壓縮列表):當列表的元素個數小於list-max-ziplist-entries配置(默認512個),同時列表中每一個元素的值都小於list-max-ziplist-value配置時(默認64字節),Redis會選用ziplist來做爲列表的內部實現來減小內存的使用。

·linkedlist(鏈表):當列表類型沒法知足ziplist的條件時,Redis會使用linkedlist做爲列表的內部實現。

四、使用場景

一、消息隊列:

Redis的lpush+brpop命令組合便可實現阻塞隊列,生產者客戶端使用lrpush從列表左側插入元素,多個消費者客戶端使用brpop命令

阻塞式的「搶」列表尾部的元素,多個客戶端保證了消費的負載均衡和高可用性。

二、文章列表

每一個用戶有屬於本身的文章列表,現須要分頁展現文章列表。此時能夠考慮使用列表,由於列表不可是有序的,同時支持按照索引範圍獲取元素。

實際上列表的使用場景不少,在選擇時能夠參考如下口訣:

·lpush+lpop=Stack(棧)

·lpush+rpop=Queue(隊列)

·lpsh+ltrim=Capped Collection(有限集合)

·lpush+brpop=Message Queue(消息隊列)

 

參考資料:《Redis開發與運維》

相關文章
相關標籤/搜索