1. 程式人生 > >redis資料庫結構

redis資料庫結構

一 全域性命令

1.1 檢視所有的key

keys *

1.2key的總數

dbsize

1.3 檢查key是否存在

exists username

1.4 刪除key

del password

1.5key過期,超過時間自動刪

expire hello 5

可以通過ttl觀察剩餘時間

ttl hello

1.6 檢視key的資料結構型別

type key,不存在這個key就返回none

比如:type username

 

二 資料結構和內部編碼

type命令實際上返回的就是當前key的資料結構型別,分別是:

string(字串),hash(雜湊),list(列表),set(集合),zset(有序集合)

但是這些只是redis對外的資料結構。

實際上每一種資料結構都有自己底層的內部編碼實現,redis會在合適的場合選擇合適的內部編碼,比如list資料結構包含了linkedlist和ziplist兩種內部編碼。我們可以通過object encoding key查詢內部編碼

 

三 單執行緒架構

Redis使用的是單執行緒架構和I/O多路複用模型來實現高效能記憶體資料庫服務。

單執行緒

優點:不會涉及到鎖,也不會涉及到執行緒切換而消耗CPU

缺點:無法利用多核CPU效能

 

多執行緒:

優點:可以充分利用多核CPU的效能

缺點:會涉及到競態問題,就會涉及到鎖;另外執行緒太多,上下文切換頻繁,會給CPU消耗帶來不好的影響

為什麼Redis單執行緒還能保持高效的效能呢?

第一:基於記憶體的訪問,Redis將所有資料放入記憶體,這個速度是很快的,這也是高效最重要的原因

第二:非阻塞I/O,Redis使用事件驅動模型epoll多路複用實現

第三:單執行緒避免的高併發的時候,多執行緒的鎖的問題和執行緒切換的CPU開銷的問題

第四:雖然是單執行緒的,我們還可以通過多例項來彌補。

 

什麼是多路複用?

多路指的是多個網路連線,而複用指的是複用同一個執行緒,即多個網路連線複用同一個執行緒。怎麼實現的呢?Linux核心提供了select,poll,epoll等系統呼叫。

select:

# 監視的檔案描述符(fd)分為三類:writefds(寫事件集合)、readfds(讀事件集合)、exceptfds(異常事件集合)

# 呼叫底層select函式阻塞等待事件發生

# 輪詢所有事件描述符集合,檢查是否有事件發生,如果有就進行處理

# select 能夠監視的檔案描述符的數量上有限制,在linux上是1024

 

poll:

本質上和select差不多。poll使用pollfd這種結構,包含了要監視的事件和發生的事件

# 呼叫底層poll函式

# 輪詢的時候同時檢查這三種事件是否發生

# 但是pollfd並沒有最大數量限制

 

epoll:

# 沒有最大併發連線的限制,能開啟的FD的上限遠大於1024

# 不會輪詢所有的描述符,而只是去

# 記憶體拷貝,利用mmap()檔案對映記憶體加速與核心空間的訊息傳遞

 

四 字串

4.1 命令

4.1.1 設定值 set/setnx

set key value [ex seconds] [px milliseconds][nx|xx]

ex: 設定秒級別的過期時間

px: 設定毫秒級別的過期時間

nx: key必須不存在,才可以設定成功

xx: key必須存在才可以設定成功

192.168.3.200:6379> set name henry ex 10 nx

OK

等價於setnx namehenry

192.168.3.200:6379> set color yellow

OK

192.168.3.200:6379> set color white px 100000 xx

 

4.1.2 批量設定值 mset

mset ip 192.168.3.20 port 8080

 

4.1.3 獲取值,如果獲取的key不存在則返回null

get key

 

4.1.4 獲取多個keymget,不能存在的key值為nil

mget key [……key]

mget ip port

 

mget 和 get區別:

批量操作命令可以有效提高開發效率,加入沒有mget這樣的命令,要執行n次get命令的時間:

N次get時間 = N次網路時間 + N次命令執行時間

如果使用mget N 個key呢?

N次get時間 = 1次網路時間 + N次命令執行時間

但是批量操作,雖然有助於提升效率,但是並不是無節制的,數量過多可能造成Redis阻塞

 

4.1.5 自增自減

4.1.5.1 自增incr

incr, 用於自增操作

incr key

值不是整數返回錯誤;值是整數,返回自增後的結果;key不存在,按照值為0自增

4.1.5.2指定數字自增incrby

incrby key 10

 

4.1.5.3 自減 decr

decr key

 

4.1.5.4 自減指定數字decrby

decrby key 1

 

4.1.6 追加值

向字串尾部增加值:append keyvalue

 

4.1.7 求字串長度

strlen key

 

4.1.8 設定值並返回原來的值

getset key value

192.168.3.200:6379> getset address "RoyalRoad #1204"

(nil)

192.168.3.200:6379> getset address "MusicBlock"

"Royal Road #1204"

 

 

4.1.9 獲取部分字串

getrange key start end

192.168.3.200:6379> getrange address 0 4

"Music"

 

4.2 內部編碼

int: 8個位元組長整型

embstr: 小於等於39個位元組的字串

raw: 大於39個位元組的字串

 

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

192.168.3.200:6379> set desc "這個圖和blocking IO的圖其實並沒有太大的不同,事實上,還更差一些。因為這裡需要使用兩個system call (select 和 recvfrom),而blocking IO只調用了一個system call (recvfrom)。但是,用select的優勢在於它可以同時處理多個connection。"

192.168.3.200:6379> object encoding desc

"raw"

192.168.3.200:6379> set num 1234

OK

192.168.3.200:6379> object encoding num

"int"

192.168.3.200:6379> object encoding ip

"embstr"

 

五 雜湊型別

Redis中,雜湊型別是指鍵值本身又是一個鍵值對結構,即類似於字典的形式

我們知道,如果要儲存使用者資訊有2種方式:

第一種:使用者ID為key,值為使用者物件

優點:簡單

缺點:需要序列化和反序列化,如果要修改某個物件屬性,需要取回該物件,並且修改時需要考慮併發的問題。

第二種:通過修改標籤,使得標籤唯一,比如user:{id}:name,user:{id}:age諸如此類,這樣的話,我們不會涉及到序列化和反序列化,也不會涉及到併發問題,但是這樣的話會有很多的key,對於記憶體來說也是不太好的

所以雜湊能夠很好解決這個問題:

可以保證key只有一個,field-value保證了我可以取任意user屬性,而不會進行序列化和反序列化的問題,也沒有併發的問題。

 

5.1 命令

5.1.1 設定值,成功返回1,錯誤返回0

hset key field value

192.168.3.200:6379> hset user:1 name "nickyzhang"

(integer) 1

192.168.3.200:6379> hset user:1 age 30

(integer) 1

192.168.3.200:6379> hset user:1 address"roayl road #145"

 

5.1.2 獲取值,沒有返回nil

hget key field

192.168.3.200:6379> hget user:1 name

"nicky zhang"

192.168.3.200:6379> hget user:1 address

"roayl road #145"

192.168.3.200:6379> hget user:1 company

(nil)

 

5.1.3 刪除field

hdel key field [field….]

hdel user:1 mail1

hdel user:1 mail1 mail2

 

5.1.4 計算field個數

hlen key

hlen user:1

 

5.1.5 批量設定或獲取filed-value

hmset key field value [field value……]

hmget key field [field ……]

hmset product:1000 displayName "楊小妖進口安第斯山脈尊貴駱馬絨大衣阿爾巴卡羊駝絨羊毛呢外套冬" price 2389.45 review 784

hmget product:1000 displayName review

 

5.1.6 判斷field是否存在

hexists key field

hexists product:1000 review

 

5.1.7 獲取所有field

hkeys key

hkeys user:1

 

5.1.8 獲取所有value

hvals key

hvals product:1000

5.1.9 獲取所有field-value

hgetall key

192.168.3.200:6379> hgetall user:1

1) "name"

2) "nicky zhang"

3) "age"

4) "30"

5) "address"

6) "roayl road #145"

 

最後幾個命令注意了,在實際中慎用,因為redis是單執行緒的,所以取到全部資料然後遍歷,這個比價耗時,會影響其他客戶端的請求

 

5.1.10自增

hincrby hincrbyfloat

hincrby key field increment

hincrbyfloat key field increment

hincrby user:1 age 10

hincrbyfloat product:1000 price 5.5

 

5.1.11計算value字串長度

hstrlen key field

hstrlen user:1 name

 

5.2 內部編碼

5.2.1ziplist

壓縮列表:當雜湊表的元素個數小於hash-max-ziplist-entries配置,預設512的時候,同時所有值都小於hash-max-ziplist-value的配置,預設64位元組時,Redis使用ziplist作為雜湊的內部實現,所以比之hashtable更加節約記憶體

5.2.2hashtable

當雜湊型別無法滿足ziplist的條件時,Redis會使用hashtable作為雜湊的內部實現,因為此時的ziplist讀寫效率會下降。

192.168.3.200:6379> object encoding product:1000

"hashtable"

192.168.3.200:6379> object encoding user:1

"ziplist"

 

雜湊型別和關係型資料庫表的比較:

# 關係型資料庫可以做複雜的查詢,但是Redis 的雜湊比較困難

六 列表

用來儲存多個有序的字串,一個列表最多可以儲存2^32-1個元素。Redis中可以對列表兩端插入(push)和彈出(pop),還可以獲取指定範圍內的元素列表,或者指定下標的元素。所以他既可以充當棧又可以充當佇列的角色

 

 

 

6.1 命令

6.1.1 新增

6.1.1.1 右邊新增

rpush key value

rpush animals hadoop

6.1.1.2 左邊新增

lpush key value

lpush animals hive

6.1.1.3 某個元素前或者後新增

linsert key before|after pivot value

在列表key中查詢value為pivot的元素的前或者後插入value

linsert animals after hadoop pig

192.168.3.200:6379> lrange animals 0 -1

1) "hive"

2) "hadoop"

3) "pig"

 

6.1.2 查詢

6.1.2.1 獲取指定範圍內的元素列表

lrange key start end(包括start和end)

lrange animals 0 4

lrange animals 0 -1表示所有

 

6.1.2.2 獲取指定索引下標的元素

lindex key index

lindex animals 2

6.1.2.3 獲取列表長度

llen key

llen animals

6.1.3 刪除

6.1.3.1 左側彈出元素

lpop key

lpop animals

6.1.3.2 右側彈出元素

rpop key

rpop animals

6.1.3.3 刪除指定元素

lrem key count value

從列表中找到等於value的元素進行刪除,根據count的不同分為三種情況:

# count > 0: 從左到右,刪除最多count個元素

lrem animals 1 tigers

# count < 0: 從右到左 刪除最多|count|個元素

lrem animals -2 tigers

# count = 0:刪除所有

lrem animals 0  tigers

6.1.3.4 按照索引範圍修建列表

ltrim key start end

那麼就只會保留start+1 到 end+1個元素

192.168.3.200:6379> ltrim animals 2 5

OK

192.168.3.200:6379> lrange animals 0 -1

1) "panda"

2) "hive"

3) "hadoop"

4) "pig"

只會保留3-6上的元素

6.1.4 修改

lset key index newvalue

lset animals 3 pigs

6.1.5 阻塞

blpop key [key……] timeout

brpop key [key……] timeout

如果列表為空:timeout=3,那麼客戶端需要等待3秒才能返回,如果timeout=0,那麼客戶端一直等待下去,直到列表不為空

blpop fruits 0 會一直等待 直到fruits這個key中有資料才返回

brpop fruits 10 會一直等待10秒,不管有沒有資料都返回,如果10秒內fruits有資料,也返回

如果有多個客戶端同時在阻塞等待,由於是單執行緒的,那麼同一時刻肯定只有一個可以返回

# 列表不為空,會立即返回

相關推薦

redis資料庫結構

一 全域性命令 1.1 檢視所有的key keys * 1.2key的總數 dbsize 1.3 檢查key是否存在 exists username 1.4 刪除key del password 1.5key過期,超過時間自動刪 expi

Redis資料庫結構與讀寫原理

此文已由作者趙計剛薪授權網易雲社群釋出。 歡迎訪問網易雲社群,瞭解更多網易技術產品運營經驗。 1、資料庫結構 每一個redis伺服器內部的資料結構都是一個redisDb[],該陣列的大小可以在redis.conf中配置("database 16",預設為16),而我們所有的快取操作

redis資料庫結構設計

    之前遊戲開發服務端都是用純c++來寫,現在很多寫遊戲伺服器越來越傾向指令碼語言,因為用c++來寫一些邏輯的確是痛苦之極,當然如果追求效率的還是用c/c++實現更好。 最近時間自己通過研究瞭解雲風寫的skynet框架學習了lua,研究skynet其實是想把這框架用到公

雲風開發筆記(2) Redis資料庫結構設計

使用者系統使用 email 來做使用者名稱,但在資料庫中的唯一標識是一個 uid 。使用者應該允許修改登陸名(使用者很可能更換 email)。使用者的身份識別是用 id 來定位的。所以,在資料庫中就應該有如下幾組 Key : account:count idaccount:userlist set(id)a

Redis資料庫結構介紹

首先Redis是採用字典結構以健值對形式進行存取的 當我們查詢2的時候就查出了對應的 color,name,price屬性所對應的值, 如果這裡我們要想多加一個屬性怎麼辦? id為1的增加了date的值,那麼對於2和3來說date欄位值是冗餘的,可想而知當不同的資料需要

Redis資料庫結構和持久化

Redis資料庫,持久化 資料庫 Redis伺服器將所有的資料庫都儲存在伺服器狀態redis.h/redisServer結構的

redis 體系結構

alt 客戶端命令 mem key ges 並不是 不出 字符串 get 程序strings key-value 類型 ,value不僅是String,也可以是數字.使用strings 類型可以完全實現目前 Memcache 的功能,並且效率更高,還可以享受redis的

redis String結構

分享圖片 img key 字符 append 結構 字符的範圍 gets nbsp 1. 設置c的過期時間為100s 2. psetex的單位為毫秒 10000毫秒 3. getrange 獲得字符的範圍 4. getset 先獲得舊的

redis hash結構如何設置過期時間

hash結構 處理方式 name set 沒有 tex 嚴重 實現 127.0.0.1 Redis中有個設置時間過期的功能,即通過setex或者expire實現,目前redis沒有提供hsetex()這樣的方法,redis中過期時間只針對頂級key類型,對於hash類型是

三十七、python學習之Redis資料庫

一、簡介 1.Nosql: 1.1.什麼是Nosql: 一類新出現的資料庫(not only sql),他的特點: (1)不支援 SQL語法。 (2)儲存結構跟傳統的關係型資料庫的那種關係表完全不同,nosql中儲存的資料都是鍵值對的形式。 (3)No

Spring Boot中使用Redis資料庫實戰

一 新增依賴 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>

Redis 資料庫keys 命令的模糊查詢

文章目錄 Redis 資料庫keys 命令的模糊查詢 1、支援的萬用字元 2、* 萬用字元 3、?萬用字元 4、[ ]匹配

redis學習(二) redis資料結構介紹以及常用命令

redis資料結構介紹   我們已經知道redis是一個基於key-value資料儲存的資料結構資料庫,這裡的key指的是string型別,而對應的value則可以是多樣的資料結構。其中包括下面五種型別:   1.string 字串    string字串型別是redis最基礎的資料儲存型別。

20181021 Spring使用Redis資料庫

一、linux下redius的安裝 1.下載https://redis.io/download 2.redis圖形化工具redisClient 3.將下載的包上傳到linux上 4.解壓 : tar -zxvf redis檔名.tar.gz 5.進入解壓後的目錄,執行 make 命令 ①若報

Redis資料庫雲端最佳技術實踐

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~ 本文由騰訊雲資料庫 TencentDB發表於雲+社群專欄 鄒鵬,騰訊高階工程師,騰訊雲資料庫Redis負責人,多年資料庫、網路安全研發經驗。在網路、計算、儲存、安全等領域有深入的研究和豐富的產品化經驗。 在Redis、MySQL等資料庫

Redis資料庫如何快速瞭解並使用(詳解)(第一篇)(共五篇)

Redis是什麼 Redis是一個開源的資料庫。底層由C語言編寫、開源、支援網路、 基於記憶體也可持久化的日誌型,高效能的key-Value資料庫。 通常被稱為資料結構伺服器, 因為值Value的型別可以為字串(String)、雜湊(Map)、列表(list)、集合(sets)、有序集合(s

怎樣從外網訪問本地的Redis資料庫

本地安裝了一個Redis資料庫,只能在區域網內訪問到,怎樣從外網也能訪問到本地的Redis資料庫呢?本文將介紹具體的實現步驟。 1. 準備工作 1.1 安裝並啟動Redis資料庫 預設安裝的Redis資料庫埠是6379。 2. 實現步驟 2.1 下載並解壓holer軟體包

[最新]織夢dedecms5.7資料庫結構詳細說明-附表名與欄位名

織夢dedecms-v5.7資料表結構詳細說明-附表名與欄位名,新手入門學習必備。   1、dede_addonarticle:附加文章表  表名:dede_addonarticle(ENGINE=MyISAM/CHARSET=utf8) 說明

Redis資料庫操作

import redis pool=redis.ConnectionPool(host='127.0.0.1',port=6379,decode_responses=True) r=redis.Redis(connection_pool=pool) # set測試 # r.sadd('test_

深入剖析Redis系列(八) - Redis資料結構之集合

前言 集合(set)型別也是用來儲存多個 字串元素,但和 列表型別 不一樣的是,集合中 不允許有重複元素,並且集合中的元素是 無序的,不能通過 索引下標 獲取元素。 如圖所示,集合 user:1:follow 包含著 "it"、"music"、"his"、"sports