Java-Redis(知識點及實際項目運用中)(一)

Java-Redis(知識點及實際項目運用中)(一)

1、簡介:

1.1、數據結構

作為 key-value 型數據庫,Redis 提供了 鍵(Key)鍵值(Value)的映射關係。但是,除了常規的 數值或字符串,Redis 的鍵值(Value)還可以是一下形式之一:

strings(byte數組):byte數組,可以包含任何數據,圖片、序列等;最大上限 1G字節。

Lists(列表):先入後出

Sets(集合):

Sorted sets(有序集合):

Hashes(哈希表):

鍵值的數據類型決定了該鍵值支持的操作。Redis 支持諸如列表、集合或有序集合的交集、並集、查集等 高級原子操作;同時如果鍵值的類型是普通數字,Redis則提供自增等原子操作。

1.2、持久化

通常,Redis將數據存儲於內存中,或被配置為使用虛擬機內存。通過兩種方式可以實現數據持久化: 使用截圖方式,將內存中的數據不斷寫入磁盤;或使用類似於 MySQL 的日誌方式,記錄每次更新的日誌 。前者性能比較高,但可能會引起一定程度的數據丟失;後者相反。

1.3、主從同步

Redis 支持將數據同步到多各從庫上,這種特性對提高讀寫性能非常有益。

2、數據類型及操作

2.1、strings

set設置 key 值get獲取 key 值setnxnx(not exist),設置 key 值, 如果key已存在返回 0getset設置 key 的值,返回 key 的舊值setex指定鍵值對應的有效期 setex haircolor 10 redgetrange獲取 key 值的子字符串 getrange name 0 6setrange設置 key 值的子字符串 setrange key 4 bbbmset一次設置多個key值,成功返回OK 失敗 0mget一次獲取多個 key 的值,如果key不存在,則返回 nilmsetnx同上,失敗返回0,沒有任何值被設置,不會覆蓋已存在的keyincr對 key的值做 ++ 操作,並返回新值 incr 一個不是 int 的 value 會返回錯誤incrby加指定值,返回新值;key不存在會設置新值,並默認原值為 0decr對key的值做 — — 操作,decr 一個不存在 key,則設置 key 為-1decrby同 decr,減指定值append給指定 key 的字符串值追加 value,返回新字符串值的長度。strlen取指定 key 的 value 值的長度。

2.2、lists

list 鏈表結構,主要操作pushpop、獲取一個範圍所有值等等,操作中 key 理解為鏈表的名字。

Redis 的 list 類型其實就是一個每個子元素都是 string 類型的雙向鏈表。鏈表的最大長度是(2的 32 次方)。我們可以通過 push,pop 操作從鏈表的頭部或者尾部添加刪除元素。這使得 list既可以用作棧,也可以用作隊列。

有意思的是 list 的 pop 操作還有阻塞版本的,當我們[lr]pop 一個 list 對象時,如果 list 是空,或者不存在,會立即返回 nil。但是阻塞版本的 b[lr]pop 可以則可以阻塞,當然可以加超時時間,超時後也會返回 nil。為什麼要阻塞版本的 pop 呢,主要是為了避免輪詢。舉個簡單的例子如果我們用 list 來實現一個工作隊列。執行任務的 thread 可以調用阻塞版本的 pop 去獲取任務這樣就可以避免輪詢去檢查是否有任務存在。當任務來時候工作線程可以立即返回,也可以避免輪詢帶來的延遲。操作:

lpushrpushlinsertlsetlremltrimlpoprpoprpoplpushlindexllen

2.3、sets

set 是集合,和我們數學中的集合概念相似,對集合的操作有添加刪除元素,有對多個集合求交併差等操作,操作中 key 理解為集合的名字。

set 的是通過 hash table 實現的,所以添加、刪除和查找的複雜度都是 O(1)。hash table 會隨著添加或者刪除自動的調整大小。需要注意的是調整 hash table 大小時候需要同步(獲取寫鎖)會阻塞其他讀寫操作,可能不久後就會改用跳錶(skip list)來實現,跳錶已經在 sorted set 中使用了。關於 set 集合類型除了基本的添加刪除操作,其他有用的操作還包含集合的取並集(union),交集(intersection),差集(difference)。通過這些操作可以很容易的實現 sns中的好友推薦和 blog 的 tag 功能。

sadd向名稱為key的set中添加元素,smembers查看元素srem刪除 set中指定元素 srem set "one"spop隨機刪除並返回這個元素sdiffstoresdiffstore set4 set2 set3返回給定key與第一個key的差集,並將結果存於 set4sdiffsdiff set1 set2,返回set1 的差集sinter返回兩個set 的交集部分sinterstoresinterstore set5 set2 set3 set2 set3的並集存於 set5sunion返回所有給定 key 的並集sunionstore返回所有給定 key 的並集,並將結果存為另一個 keysmovesmove set2 set3 three ;從第一個 key 對應的 set 中移除 member 並添加到第二個對應 set 中scard返回名稱為 key 的 set 的元素個數sismenbersismember set value ;如果 value在 set中返回 1,不在 0srandmember隨機返回 set 的一個元素,但是不刪除元素

2.4、sorted set

sorted set 是 set的一個升級版,它在 set的基礎上增加一個順序屬性,這一屬性在添加 修改元素的時候可以指定,每次指定後,zset 會自動重新按新的值調整順序。可以理解為有兩列的 mysql 表,一列存 value,一列存順序。操作中 key 理解為 zset 的名字。

和 set 一樣 sorted set 也是 string 類型元素的集合,不同的是每個元素都會關聯一個 double類型的 score。sorted set 的實現是 skip list 和 hash table 的混合體。

當元素被添加到集合中時,一個元素到 score 的映射被添加到 hash table 中,所以給定一個元素獲取 score 的開銷是 O(1),另一個 score 到元素的映射被添加到 skip list,並按照 score 排序,所以就可以有序的獲取集合中的元素。添加,刪除操作開銷都是 O(log(N))和 skip list 的開銷一致,redis 的 skip list 實現用的是雙向鏈表,這樣就可以逆序從尾部取元素。sorted set 最經常的使用方式應該是作為索引來使用.我們可以把要排序的字段作為 score 存儲,對象的 id當元素存儲。

zaddzadd myzset score "元素" ; 向 key 的 zset 中添加元素 score 用於排序,如果元素已存在score 更新元素順序,以最後一次設置為準zrem刪除名稱為 key 的 zset 中的元素zincrbyzset 中已經存在元素 ,則該元素的 score 相加;否則向集合中添加該元素,其 score 的值為 添加時的scorezrank返回元素在key中的排名(元素下標,小到大)zrangezrange myzset3 0 -1 withscoreszrevrank返回元素在zset的排名(大到小)zrevrange返回zset(按 score 從大到小排序)中的 index 從 start 到 end 的所有元素zrangebyscore返回集合中 score 在給定區間的元素zcount返回集合中 score 在給定區間的數量zcard返回集合中元素個數zscore返回給定元素對應的 scorezremrangebyrank刪除集合中排名在給定區間的元素

zremrangebyscore刪除集合中 score 在給定區間的元素

2.5、hashes

hash適合存儲對象,hash 比將對象屬性單個存儲為string,更便於存取和節省內存;

省內存的原因是新建一個hash 對象時開始是用 zipmap(又稱 small hash) 來存儲。

zipmap 不是hash table 但是相比 hash可以節省不少元素開銷。如果元素字段過多 redis會自動將zipmap 替換成正常的 hash實現,這個限制大小可以手動配置:

hash-max-zipmap-entries 64 #配置字段最多 64 個

hash-max-zipmap-entries 64 #配置字段最多 64 個

hset設置 hash field 值,如果 key 不存在,則先創建。hsetnx設置 hash field 值,如果 key 不存在,則先創建。如果 field 已經存在,返回 0,nx 是not exist 的意思。hmset同時設置 hash 的多個 field。hget獲取指定的 hash field。空值 nilhmget獲取全部指定的 hash filed。hincrby指定的 hash filed 加上給定值。hexists

測試指定 field 是否存在。hlen返回指定 hash 的 field 數量。hdel返回指定 hash 的 field 數量。hkeys返回 hash 的所有 fieldhvals返回 hash 的所有 value。hgetall獲取某個 hash 中全部的 filed 及 value。

3、Redis 常用命令

Redis 提供了豐富的命令(command)對數據庫和各種數據類型進行操作,這些 command可以在 Linux 終端使用。在編程時,比如各類語言包,這些命令都有對應的方法。

3.1、鍵值相關命令

keys:keys *

用表達式*,代表取出所有的 key;

exists: exists key

確認這個 key是否存在(不存在 0 | 存在1);

del:del key

刪除一個 key;

expire:expire key 10

設置這個 key 的過期時間(單位:秒) ;ttl 獲取這個key ,-1 代表過期;

move:move key 庫名

將當前數據庫中的 key 轉移到其它數據庫中;

persist:persist key

移除給定 key的活期時間;

randomkey:randomkey

隨機返回一個 key

rname:rname oldname newname

重命名

type:type key

返回 key的類型

3.2、服務器相關命令

ping:ping 連接是否正常

echo: echo string

在命令行打印 string

select:select 數據庫名

選擇數據庫,Redis 數據庫編號從 0~15,可以任意選擇一個數據庫進行操作

quit:quit 退出連接

dbsize:dbsize 返回當前數據庫 key的數目

info:info 獲取服務器的信息和統計

此結果用於說明服務器的基礎信息,包括版本、啟動時間等。

monitor:實時轉儲收到的請求。

config get:config get dir 獲取服務配置信息

獲取 dir 這個參數配置的值;獲取所有配置信息 config get *

flushdb:flushdb 刪除當前數據庫的所有 key

flushall:flushall 刪除所有數據庫中所有 key

4、適用場景:

4.1、獲取最新 N 個數據的操作:

比如典型的取網站最新文章,通過下面方式,我們可以將最新的 5000 條評論的 ID 放在 Redis 的 List 集合,並將超出集合部分從數據庫獲取。

使用 LPUSH latest.comments命令,向集合中插入數據,插入完成後再用 LTRIM latest.comments 0 5000命令使其永遠只保存最近 5000 個 ID 然後我們在客戶端獲取某一項評論時可以用下面

邏輯。

FUNCTION get_latest_comments(start,num_items):
 id_list = redis.lrange("latest.comments",start,start+num_items-1)
 IF id_list.length < num_items
 id_list = SQL_DB("SELECT ... ORDER BY time LIMIT ...")
 END
 RETURN id_list
END

如果還有不同的篩選維度,比如某個分類的最新 N 條,可以再建一個按此分類的 List,只存 ID 的話,Redis非常高效。

4.2、排行榜應用,取 TOP N操作:

4.3、需要精準設定過期時間的應用:

4.4、計數器應用:

4.5、Uniq 操作,獲取某段時間所有數據排重值:

4.6、實時系統,反垃圾系統

4.7、Pub/Sub 構建實時消息系統

4.8、構建隊列系統

4.9、緩存


分享到:


相關文章: