1. 程式人生 > 其它 >linux kernel makefile 分析 - 6

linux kernel makefile 分析 - 6

前置準備

安裝

$ wget https://download.redis.io/releases/redis-6.2.6.tar.gz
$ tar xzf redis-6.2.6.tar.gz
$ cd redis-6.2.6
$ make

啟動服務端

$ src/redis-server

啟動客戶端

$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"

基礎知識

Redis 的基本資料型別

keys * :查詢所有的 key

Redis Strings

基礎操作

Redis 字串型別是可以與 Redis 鍵關聯的最簡單的值型別。它是Memcached中唯一的資料型別,因此新手在Redis中使用它也是非常自然的。

由於 Redis 鍵是字串,因此當我們也將字串型別用作值時,我們會將一個字串對映到另一個字串。

> set mykey somevalue
OK
> get mykey
"somevalue"

請注意,如果鍵已存在,SET 將替換已儲存在鍵中的任何現有值,即使該鍵與非字串值相關聯也是如此。

原子增量

字串是 Redis 的基本值,您也可以使用它們執行一些有趣的操作。例如,一個是原子增量:

incr:+1 incrby:+val decr:-1 decrby:-val GETSET:重置並返回

> set counter 100
OK
> incr counter
(integer) 101
> incr counter
(integer) 102
> incrby counter 50
(integer) 152
> decr counter
(integer) 151
> decrby counter 10
(integer) 141
> getset counter 0
(integer) "100"
> get counter
"0"
設定或檢索多個鍵的值

mset key val key val mget key key

> mset key1 val1 key2 val2
OK
> mget key1 key2
1) "val1"
2) "val2"
更改和查詢 key

set key val exists key del key type key

> get key1
"val1"
> set key1 val11
OK
> get key1
"val11"
> type key1
string
> exists key1
(integer) 1
> del key1
(integer) 1
> exists key1
(integer) 0
設定 key 過期時間

set key val ex 10 EX seconds PX milliseconds

> set key1 100 ex 10
OK
> get key1
(nil)

Redis Lists

從非常一般的角度來看,List只是一個有序元素的序列:10,20,1,2,3是一個列表。但是,使用陣列實現的列表的屬性與使用連結列表實現的列表的屬性非常不同。

Redis 列表通過連結列表實現。這意味著,即使您在列表中有數百萬個元素,在列表的頭部或尾部新增新元素的操作也會在恆定時間內執行。使用 LPUSH 命令將新元素新增到包含 1000 萬個元素的列表的頭部的速度與將元素新增到包含 1000 萬個元素的列表頂部的速度相同。

缺點是什麼?在使用 Array 實現的列表中,按索引訪問元素的速度非常快(常量時間索引訪問),而在連結串列實現的列表中(其中操作需要與被訪問元素的索引成比例的工作量)中,訪問元素的速度並不快。

Redis列表是用連結串列實現的,因為對於資料庫系統來說,能夠以非常快的方式將元素新增到非常長的列表中至關重要。正如您稍後將看到的那樣,另一個強大的優勢是Redis列表可以在恆定的時間內以恆定的長度進行。

當快速訪問大型元素集合的中間很重要時,可以使用不同的資料結構,稱為排序集。本教程稍後將介紹已排序的集。

基礎操作

LPUSH :將新元素新增到列表中左側(在頭部)

RPUSH:將新元素新增到列表中右側(在末尾)

LRANGE:命令從列表中提取元素範圍,採用兩個索引,即要返回的範圍的第一個元素和最後一個元素。兩個索引都可以為負數,告訴 Redis 從末尾開始計數:所以 -1 是最後一個元素,-2 是列表的倒數第二個元素,依此類推。

> rpush mylist A
(integer) 1
> rpush mylist B
(integer) 2
> lpush mylist first
(integer) 3
> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
彈出元素

Redis Lists 定義的一個重要操作是彈出元素的功能。彈出元素是同時從列表中檢索元素和從列表中消除元素的操作。您可以從左側和右側彈出元素,類似於在列表兩側推送元素的方式:

RPOP:從右側彈出

LPOP:從左側彈出

沒有值了返回(nil),且這個 key 也將不存在。

> lrange mylist 0 -1
1) "first"
2) "A"
3) "B"
> rpop mylist
"B"
> lrange mylist 0 -1
1) "first"
2) "A"
> lpop mylist
"first"
> lrange mylist 0 -1
1) "A"
> lpop mylist
"A"
> lpop mylist
(nil)
使用場景
  • 記住使用者釋出到社交網路中的最新更新。
    • 每次使用者釋出新照片時,我們都會將其ID新增到LPUSH列表中。
    • 當用戶訪問主頁時,我們使用以獲取最新的10個已釋出專案。LRANGE 0 9
  • 程序之間的通訊,使用使用者-生產者模式,其中生產者將專案推送到列表中,消費者(通常是工作執行緒)使用這些專案和執行的操作。Redis 具有特殊的列表命令,使此用例更加可靠和高效。
上限列表

LTRIM 命令類似於 LRANGE,但它不顯示指定的元素範圍,而是將此範圍設定為新的列表值。給定範圍之外的所有元素都將被刪除。

LTRIM:只保留指定範圍內的值,範圍外的值全部刪除。

> rpush mylist 1 2 3 4 5 6
(integer) 6
> ltrim mylist 0 2
OK
> lrange mylist 0 -1
1) "1"
2) "2"
3) "3"
阻止對列表執行的操作

列表具有一個特殊功能,使它們適合於實現佇列,並且通常作為程序間通訊系統的構建塊:阻塞操作。

使用 LPUSH 和 RPOP 進行操作時列表可能為空,無需處理任何內容,因此 RPOP 僅返回 NULL。在這種情況下,使用者被迫等待一段時間,然後使用 RPOP 重試。這稱為輪詢,在此上下文中不是一個好主意,因為它有幾個缺點:

  • 強制 Redis 和客戶端處理無用的命令(當列表為空時,所有請求都不會完成任何實際工作,它們只會返回 NULL)。
  • 為專案的處理新增延遲,因為在工作執行緒收到 NULL 後,它會等待一段時間。

因此,Redis實現了稱為 BRPOP 和 BLPOP 的命令,它們是 RPOP 和 LPOP 的增強版本,能夠在列表為空時阻止:只有當將新元素新增到列表中或達到使用者指定的超時時,它們才會返回給呼叫方。

BRPOP key [key ...] timeout

BLPOP key [key ...] timeout

> brpop mylist 5
1) "mylist"
2) "3"
> brpop mylist 5
1) "mylist"
2) "2"
> brpop mylist 5
(nil)
(5.02s)
注意點
  1. 客戶端以有序的方式提供:阻止等待列表的第一個客戶端,當元素被某個其他客戶端推送時,首先提供,依此類推。
  2. 與 RPOP 相比,返回值不同:它是一個雙元素陣列,因為它還包括鍵的名稱,因為 BRPOP 和 BLPP 能夠阻止等待來自多個列表的元素。
  3. 如果達到超時,則返回 NULL。

Redis Hashes

Redis 雜湊與欄位值對的"雜湊"外觀完全一致:

HMSET key field value [field value ...]

HGET key field

HMGET key field [field ...]

HINCRBY key field increment

> hmset user:1000 username antirez birthyear 1977 verified 1
OK
> hmget user:1000 username
1) "antirez"
> hgetall user:1000
1) "username"
2) "antirez"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"
> hget user:1000 username birthyear
(error) ERR wrong number of arguments for 'hget' command
> hmget user:1000 username birthyear
1) "antirez"
2) "1977"
> HINCRBY user:1000 birthyear 10
(integer) 1987

Redis Sets

Redis Sets 是字串的無序集合。SADD 命令將新元素新增到集合中。還可以對集合執行許多其他操作,例如測試給定元素是否已經存在,執行多個集合之間的交集,並集或差異等。

SADD key member [member ...]

> sadd myset Hello
(integer) 1
> sadd myset World
(integer) 1
> sadd myset World
(integer) 0
> smembers myset
1) "World"
2) "Hello"

SISMEMBER key member

> smembers myset
1) "World"
2) "Hello"
> sismember myset World
(integer) 1
> sismember myset test
(integer) 0

集合適用於表示物件之間的關係。例如,我們可以很容易地使用集合來實現標籤。

> sadd news:1000:tags 1 2 5 77
(integer) 4
> smembers news:1000:tags
1) "1"
2) "2"
3) "5"
4) "77"
求集合之間的交集
> sadd key1 a b c
(integer) 3
> sadd key2 c y h
(integer) 3
> SINTER key1 key2
1) "c"
將多個集合彙總複製,會進行去重操作

SUNIONSTORE destination key [key ...]

> SMEMBERS key1
1) "c"
2) "b"
3) "a"
> SMEMBERS key2
1) "c"
2) "h"
3) "y"
> SUNIONSTORE key1+2 key1 key2
(integer) 5
> SMEMBERS key1+2
1) "c"
2) "h"
3) "b"
4) "a"
5) "y"
取出元素

SPOP key [count]:取出元素的同時會將元素從集合中刪除

> spop key1+2
"y"
> spop key1+2 2
1) "a"
2) "b"
> SMEMBERS key1+2
1) "h"
2) "c"

SRANDMEMBER key [count]:之取出元素,不做其他操作

> SMEMBERS key1+2
1) "h"
2) "c"
> SRANDMEMBER key1+2
"h"
> SMEMBERS key1+2
1) "h"
2) "c"
檢視集合的數量
> SMEMBERS key1+2
1) "h"
2) "c"
> SCARD key1+2
(integer) 2

Redis Sorted sets

排序集合是一種資料型別,類似於 Set 和 Hash 之間的混合。與集合一樣,排序集由唯一的、非重複的字串元素組成。

但是,雖然集合中的元素沒有排序,但排序集中的每個元素都與一個稱為分數的浮點值相關聯(這就是為什麼型別也類似於雜湊,因為每個元素都對映到一個值)。

此外,排序集中的元素是按順序排列的(因此它們不是根據請求排序的,順序是用於表示排序集的資料結構的一個特點)。它們根據以下規則進行排序:

  • 如果 A 和 B 是兩個具有不同分數的元素,則 A > B,如果 A.分數> B.分數。
  • 如果 A 和 B 的分數完全相同,則 A > B,如果 A 字串在字典上大於 B 字串。A 和 B 字串不能相等,因為排序集只有唯一元素。
新增元素

ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...]

  • XX:僅更新已存在的元素。不要新增新元素。
  • NX:僅新增新元素。不要更新現有元素。
  • LT:僅當新分數小於當前分數時,才會更新現有元素。此標誌不會阻止新增新元素。
  • GT:僅當新分數大於當前分數時,才會更新現有元素。此標誌不會阻止新增新元素。
  • CH:修改返回值,從新增的新元素的數量,到更改的元素總數(CH是 changed 的縮寫)。更改的元素是新增的新元素和已更新分數的現有元素。因此,在命令列中指定的元素與過去具有相同分數的元素不計算在內。注意:通常 ZADD 的返回值僅計算新增的新元素的數量。
  • INCR:當指定此選項時 ZADD 的行為類似於 ZINCRBY 。在此模式下只能指定一個分數元素對。

注意:GTLTNX 選項是互斥的。

> zadd hackers 1940 "Alan Kay" 1957 "Sophie Wilson" 1953 "Richard Stallman" 1949 "Anita Borg" 1965 "Yukihiro Matsumoto" 1914 "Hedy Lamarr" 1916 "Claude Shannon"
(integer) 7
> zrange hackers 0 -1
1) "Hedy Lamarr"
2) "Claude Shannon"
3) "Alan Kay"
4) "Anita Borg"
5) "Richard Stallman"
6) "Sophie Wilson"
7) "Yukihiro Matsumoto"
> zrange hackers 0 -1 WITHSCORES
 1) "Hedy Lamarr"
 2) "1914"
 3) "Claude Shannon"
 4) "1916"
 5) "Alan Kay"
 6) "1940"
 7) "Anita Borg"
 8) "1949"
 9) "Richard Stallman"
10) "1953"
11) "Sophie Wilson"
12) "1957"
13) "Yukihiro Matsumoto"
14) "1965"