Redis不應只是初見,應該還有後續

   Redis 想必大夥應該都知道,而且肯定是用到了的。我這裏就不一一贅述了。

那麼我們就來聊一聊Redis 的來源,主要用於做什麼,有哪些優勢等等.

一、Redis 是什麼?

    來源:據說是08 年的時候有一個意大利西西里島的小夥子,在創建一個網站時候,發現的有些由於讀寫的操作頻繁,一開始是考慮的Mysql,但是發現在併發高的時候,發現怎麼優化數據庫都效果不明顯,因爲數據庫存儲的是磁盤(瓶頸也在此,磁盤的讀寫熟速度導致的),因此就決定放棄數據庫(Mysql),自己去實現一個列表結構的數據庫,但是這個數據並不是存儲在磁盤上,而是在內存上,我們都知道內存的讀寫速度跟磁盤差距很大的,因IC也提高了數據庫的get/set速度了,因此在通過利用C語言重寫這個內存數據庫,因爲內存的服務宕機時,數據是不會保存的,因此還加上了數據的持久化。這樣09年的時候,Redis就誕生。Redis( REmote DIctionary Service:遠程字典服務)

二、Redis的定位及特性

   在通常情況下如果需要數據存儲的話,我們一般都是考慮傳統的關係型數據庫的(如:Mysql,SqlServer,Oracle等.)

  關係型的數據的特點:1、一般以表結構形式存儲,二維模式   2、存儲的結構化,數據需要有固定的數據結構來適應表結構存儲 3、各表之間有一定的關聯關係(外鍵等) 4、一般都支持Sql等複雜表之間的關聯查詢,只是有些語法上存在一些差異 5、支持事物 。不足:1、擴容的話,支持垂直擴容,增加磁盤,不支持動態擴容,水平擴容支持相對複雜(分庫分表等技術) 2、表結構修改較爲複雜,數據結構相對固定  3、讀寫速度相對來說會比較慢,尤其在高速讀寫時,磁盤的I/O會是一定的瓶頸。

 在這樣的情況下,No sql (非關係型)就應運而生了。其特點: 1、存儲非固定的結構,可文本,圖形,視頻等 2、表之間無關係 3、也保證的數據的最終一致性  4、支持海量的數據存儲且保證了高併發下的讀寫效率  5、支持分佈式,能夠對數據進行分片存儲,擴容相對簡單。

No sql 根據不通的存儲類型,又有各種類型的數據庫。K-V 結構:Redis,MemcacheDB等 ,文檔:MongoDb  等等...

今天我們主要聊聊Redis,Redis的主要特點:1、數據類型豐富(String,Hash,Set, List 等)2、單機與分佈式 3、支持持久化,數據的過期策略 4、支持多種語言  5、集羣,高可用等

三、Redis 安裝與基本操作

   安裝:Redis的安裝,我的上一篇Redis安裝已經說明了,就不再贅述了(Redis 安裝

基本操作 

1、啓動:redis-server /usr/local/soft/redis-5.0.5/redis.conf

2、選擇數據庫  select 1   (默認有16個庫,0,1,..15)

3、清空當前數據庫->  flushdb  / flushall (清空所有)

4、set  key value 、get  key

具體命令參考:http://redisdoc.com/index.html

四、Redis的基本數據類型

1、String  字符類型

a、字符類型應該算是最常用的類型了。set / get 就是對String 類型的操作命令了。

b、String 可以存儲的類型包括:字符串,整數,浮點型

c、語法:set key value [expiration EX seconds|PX milliseconds][NX|XX]   具體參考官網哈

設置失效時間,基於此我們可以設置分佈式鎖,自動釋放鎖等操作

 d、存儲原理 :因爲Redis是K-V 結構的,是通過hashTable 實現的,每個鍵值對都會有一個dictEntry。如下數據結構

 key 是個字符串,而redis中沒有使用C中的字符數組,而是使用SDS, 而value 也不是作爲字符串字存儲的,而是存儲在redisObject中。

可以使用 type 命令來查看對外的類型  - > type key

在字符串內部其實還有根據value,又分了幾種編碼類型

1、int,存儲 8 個字節的長整型(long,2^63-1)。
2、embstr, 代表 embstr 格式的 SDS(Simple Dynamic String 簡單動態字符串),
存儲小於 44 個字節的字符串。
3、raw,存儲大於 44 個字節的字符串(3.2 版本之前是 39 字節)

什麼是SDS (SDS其實根據存儲的長度,又分了好幾種如:sdshdr5(2^5)sdshdr8(2^8) ...)

sds特點:1、如果需要會對sds進行動態擴容,不必擔心溢出問題  2、計算字符的長度時時間複雜度o(1).  3、可以存儲任意類型字符(如:\0)  4、可以通過判斷len判斷字符是否結束

爲什麼redis需要使用SDS來實現存儲字符串呢?

因爲redis 是通過C語言實現的,而在C中是通過char[] 數組實現字符串存儲的,而char[]是有結束標記的('\0')因此如果當字符串(音頻,視頻,圖片等文件時轉二進制時)中存在(\0)再去存儲的話,就會有問題的。因此需要只有從新自己實現了。

1、使用字符數組時,必須分配足夠的空間,否則會溢出的

2、如果需要計算字符的長度,那麼就需要遍歷數組的,時間複雜度是o(n).

3、C 中數組的字符長度的變更需要重新做內存分配

embstr 和 raw 的區別?

embstr 只會分配1次內存空間,raw 需要分配2次內存空間。因此與 raw 相比,embstr 的好處在於創建時少分配一次空間,刪除時少釋放一次空間,以及對象的所有數據連在一起,尋找方便。embstr 的壞處也很明顯,如果字符串的長度增加需要重新分配內存時,整個RedisObject 和 SDS 都需要重新分配空間,因此 Redis 中的 embstr 實現爲只讀 。embstr編碼方式和raw編碼方式在3.0版本之前是以39字節爲分界的,也就是說,如果一個字符串值的長度小於等於39字節,則按照embstr進行編碼,否則按照raw進行編碼。而在3.2版本之後,則變成了44字節爲分界。

int 和 embstr 什麼時候轉化爲 raw?

1、int ,當int存儲的不再是整數或者超過了int範圍(2^63-1),如一開始存整數1,後期有append 字符a.那麼存儲就會修改爲raw.。 還有就是一開始是:embstr 存存儲 (只讀的),後面append 一個value(需要先修改爲raw).那麼也會重新分配內存,則類型轉爲了raw.因此哪怕字符串沒超過了44。而且內部的編碼轉換不會逆轉(只能從小的轉到大的)

 應用場景:緩存,分佈式鎖,全局ID ,IP 限流等..

2、hash 哈希

hset h1 f 6
hset h1 e 5
hmset h1 a 1 b 2 c 3 d 4

存儲類型:包含鍵值對的無序散列表。value 只能是字符串,不能嵌套其他類型

Hash 不適合的場景:
1、Field 不能單獨設置過期時間
2、沒有 bit 操作
3、需要考慮數據量分佈的問題(value 值非常大的時候,無法分佈到多個節點)

存儲字符串,Hash 與 String 的主要區別?
1、把所有相關的值聚集到一個 key 中,節省內存空間
2、只使用一個 key,減少 key 衝突
3、當需要批量獲取值的時候,只需要使用一個命令,減少內存/IO/CPU 的消耗

很顯然Hash 也是K-V 結構,有點類似於HashMap ,當存儲Hash數據類型,底層實現的2種數據結構:

ziplist:OBJ_ENCODING_ZIPLIST( 當鍵和值長度都小於64個字節時,有壓縮列表結構存儲。壓縮列表->特殊編碼的雙向鏈表)
hashtable:OBJ_ENCODING_HT(當鍵值對數量小於512字節時,哈希表)

3、List 列表

該結構:可以充當隊列和棧

存儲原理:早期數據量不大的時候,用的是ZipList, 3.2的版本之後即統一用quickLis(存儲了一個雙向鏈表,每個節點都是一個ZipList)

一個QuickList 是由多個quicklistNode組成,每個quicklistNode又是由多個ZipList組成

4、Set 集合 (String 類型的無序集合,最大存儲數量 2^32-1(40 億左右)

添加一個或者多個元素 (sadd myset a b  c)

存儲實現原理:Redis 用 intset 或 hashtable 存儲 set。如果元素都是整數類型,就用 intset 存儲。
如果不是整數類型,就用 hashtable(數組+鏈表的存來儲結構)

KV 怎麼存儲 set 的元素?key 就是元素的值,value 爲 null。

應用場景:隨機獲取元素、相互關注,點贊等

5、Zset 集合(有序)

每個元素都有個分數(score),一般當 元素數量小於 128 個或所有 member 的長度都小於 64 字節 用ZipList 存儲,內部根據score倆移動進行排序 ,否則就通過跳錶(skipList + dict)存儲

什麼叫跳錶(skipList)?

原理:當新增一個值時,會計算該值的level(姑且理解爲層數)每一層都是一個鏈表,通過計算的level ,從哪一層開始比較。

1、如;新增23 ,計算的level 是 2 那麼從第二層開始比較

  23 與 7 比較 ->大於 則比較19 ->大於比較 26 小於

2、那麼下一層,比較22-> 大於,那麼在22 與 26 之間

等等還有其他的類型,後續補上...  在這裏還是得感謝gupao的老師,幫我理解這些內容。

以上內容如有敘述不當的,還請各位看官大神們多多指點..

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章