新人入坑Redis必會的吐血總結
一、什么是Redis
Redis是一個使用C語言開發的開源的高性能的key-value存儲系統,我們可以把它近似理解為Java Map。簡單來講,Redis是一種NOSQL內存數據庫,小伙伴們可不要把它理解為NO SQL(不是SQL),它的全稱是Not Only SQL(不僅僅是SQL),換個層面來講,它是一種非關系型的數據庫,它是作為關系型數據庫的良好補充,它與傳統的MySQL,Oracle不同之處在於,它是通過在內存中讀寫數據,大大提高了讀寫速度。可以說,Redis是為了解決網站高並發、高可用、高可擴展、大數據存儲等一系列問題而產生的數據庫解決方案,不可或缺的一部分。
它具有以下特點:
1、Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。
2、Redis不僅僅支持簡單的key-value類型的數據,同時還提供string、list、set、sortedset、hash等數據結構的存儲。
3、Redis支持數據的備份,即master-slave模式的數據備份。
Redis有五種鍵值類型:
-
String字符類型
-
hash散列類型
-
list列表類型
-
set集合類型
-
sortedset有序集合類型
而本文將基於Redis5.0為例來介紹Redis一些相關命令的使用和踩過的坑
二、關於Redis的安裝與啟動
環境准備
-
CentOS7 (未安裝Development Tools)
安裝教程請參看這里:https://www.cnblogs.com/ECJTUACM-873284962/p/9532043.html
在線環境
官網似乎提供了一個在線的Redis平台,鏈接在這里:http://try.redis.io/
Redis啟動
前端啟動
按照我所提供的教程安裝以后,我們只需要輸入命令redis-server即可,界面如下:
前端停止啟動
-
強制關閉:Ctrl+c
-
正常關閉[root@sakura]# redis-cli shutdown
后端啟動
因為Redis在實際使用中不會只是一個Redis單獨工作,啟動和關閉方式中的ip地址和端口號可以在配置文件中自行修改,下面會有修改方式.
啟動方式
-
需要將redis解壓之后的源碼包中的redis.conf文件拷貝到bin目錄下.直接復制粘貼即可
-
修改redis.conf文件,將daemonize改為yes(vi redis.conf進去,:/daemonize搜索).
-
使用命令后端啟動redis.命令行redis-server redis.conf(以配置文件啟動)
-
查看是否啟動成功.命令行 ps -aux | grep redis (直接查看redis的進程)
如果你之前按照我所提供的教程修改過,這一過程可以直接忽略就好
關閉方式
-
強制關閉:kill -9 PID
-
正常關閉:redis-cli -h ip地址 -p 端口號(默認端口號是6379) shutdown
在項目中,建議使用正常關閉。 因為redis作為緩存來使用的話,將數據存儲到內存中,如果使用正常關閉,則會將內存數據持久化到本地之后,再關閉。如果是強制關閉,則不會進行持久化操作,可能會造成部分數據的丟失。
Redis客戶端啟動
啟動客戶端命令:[root@sakura]# redis-cli -h ip地址 -p 端口號
由於默認IP是127.0.0.1,端口是6379,我們只需要輸入命令redis-cli即可
退出:127.0.0.1:6379> quit即可
三、Redis數據類型及常用命令講解
1、Redis-String
string使用環境:主要用於保存json格式的字符串
賦值
set key value:設定key持有指定的字符串value,如果該key存在則進行覆蓋操作,總是返回"OK",如果賦予相同的key,新的value會覆蓋老的value
example:
127.0.0.1:6379> set username zhangsan
OK
取值
get key:獲取key的value。如果與該key關聯的value不是string類型,redis將返回錯誤信息,因為get命令只能用於獲取string value;如果該key不存在,返回nil
example:
127.0.0.1:6379> get username
"zhangsan"
刪除
del key:刪除指定key,返回值是數字類型,表示刪了幾條數據
example:
127.0.0.1:6379> del username
(integer) 1
擴展
getset key value:先獲取該key的值,然后再設置該key的值
example:
127.0.0.1:6379> getset username zhangsan
(nil)
127.0.0.1:6379> keys *
1) "username"
127.0.0.1:6379> get username
"zhangsan"
incr key:將指定的key的value原子性的遞增1,如果該key不存在,其初始值為0,在incr之后的值為1,如果value的值不能轉成整型,如hello,該操作將執行失敗並返回相應的錯誤信息,相當於++(作用:統計網站訪客人數,當計數器)
example:
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> incr age
(integer) 19
decr key:將指定的key的value原子性的遞減1,如果該key不存在,其初始值為0,在incr之后的值為-1,如果value的值不能轉成整型,如hello,該操作將執行失敗並返回相應的錯誤信息,相當於--i
example:
127.0.0.1:6379> set age 18
OK
127.0.0.1:6379> decr age
(integer) 17
append key value:拼接字符串,如果該key存在,則在原有的value后追加該值,如果該key不存在,則重新創建一個key/value
example:
127.0.0.1:6379> set information hel
OK
127.0.0.1:6379> append information lo
(integer) 5
127.0.0.1:6379> get information
"hello"
incrby和decrby:只能對字符串是數字的進行操作,incrby key value是對原有的key的值增加value,而decrby key value是對原有的key的值減少value
example:
127.0.0.1:6379> get age
"17"
127.0.0.1:6379> incrby age 10
(integer) 27
127.0.0.1:6379> decrby age 10
(integer) 17
127.0.0.1:6379> get information
"hello"
127.0.0.1:6379> incrby information 10
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decrby information 10
(error) ERR value is not an integer or out of range
2、Redis-hash
Redis中的hash類型可以看成具有string key和string value的map容器,所以該類型非常適合於存儲值對象的信息。如username,password和age等。如果hash中包含很少的字段,那么該類型的數據也將僅占用很少的磁盤空間。每一個hash可以存儲4294967295個鍵值對。
hash特點:占用的磁盤空間極少
賦值:
hset key field value:為指定的key設定field/value對(鍵值對)
example:
127.0.0.1:6379> hset key1 field1 123
(integer) 1
hmset key field value[field2 value2...]:設置key中的多個field/value
example:
127.0.0.1:6379> hmset aaa name kitty age 20
OK
取值:
hget key filed:獲取指定的key的field的值
example:
127.0.0.1:6379> hget key1 field1
"123"
hmget key filed1 field2...:獲取key中的多個field的值
example:
127.0.0.1:6379> hmget aaa name age
1) "kitty"
2) "20"
hgetall key:獲取key中的所有field-value2
example:
127.0.0.1:6379> hgetall aaa
1) "name"
2) "kitty"
3) "age"
4) "20"
刪除
hdel key field[field...]:可以刪除一個或多個字段,返回值是被刪除的字段個數
example:
127.0.0.1:6379> hdel key1 field1
(integer) 1
del key:刪除整個list
example:
127.0.0.1:6379> del aaa
(integer) 1
增加數字
hincrby key field increment:設置key中的field增加increment,如age增加20
example:
127.0.0.1:6379> hmset aaa name kitty age 20
OK
127.0.0.1:6379> hincrby aaa age 20
(integer) 40
擴展命令
hexists key field:判斷指定的key中的field是否存在
example:
127.0.0.1:6379> hexists aaa name
(integer) 1
127.0.0.1:6379> hexists aaa aaaa
(integer) 0
hlen key:獲取key所包含的field的數量
example:
127.0.0.1:6379> hlen aaa
(integer) 2
hkeys key:獲得所有的字段
example:
127.0.0.1:6379> hkeys aaa
1) "name"
2) "age"
3、Redis-list
Redis中list選取的是鏈表,因為在Redis操作中,最多的操作是進行元素的增刪
賦值
lpush key value [value1 value2 ...] 在指定的key所關聯的list頭部插入所有的value,如果該key不存在,該命令在插入之前創建一個與該key關聯的空鏈表,之后再向該鏈表的頭部插入數據,插入成功,返回元素的個數。
example:
127.0.0.1:6379> lpush score1 1 2 3 4 5
(integer) 5
rpush key value [value1 value2 ...] 在該list的尾部添加元素
example:
127.0.0.1:6379> rpush score2 1 2 3 4 5
(integer) 5
取值
lrange key start end:獲取鏈表中從start到end的元素的值,start、end從0開始計數;也可以為負數,若為-1則表示鏈表尾部的元素,-2表示倒數第二個,以此類推...
example:
127.0.0.1:6379> lrange score1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379> lrange score2 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
刪值
lpop key:返回並彈出指定的key關聯的鏈表中的第一個元素,即頭部元素。如果該key不存在,返回nil;若key存在,則返回鏈表的頭部元素
example:
127.0.0.1:6379> lpop score1
"5"
127.0.0.1:6379> lpop score2
"1"
rpop key:從尾部彈出元素
example:
127.0.0.1:6379> rpop score1
"1"
127.0.0.1:6379> rpop score2
"5"
擴展
llen key:返回指定的key關聯的鏈表中的元素的數量
example:
127.0.0.1:6379> llen score1
(integer) 3
127.0.0.1:6379> llen score2
(integer) 3
lrem key count value:刪除count個值為value的元素,如果count大於0,從頭到尾遍歷並刪除count個值為value的元素,如果count小於0,則從尾到頭遍歷並刪除,如果count等於0,則刪除鏈表中所有等於value的元素。
example:
127.0.0.1:6379> lrem score1 1 2
(integer) 1
127.0.0.1:6379> lrem score2 1 2
(integer) 1
通過索引替換
lset key index value:設置鏈表中的index的腳標的元素值,0代表鏈表的頭元素,-1代表鏈表的尾元素。操作鏈表的腳標不存在則拋出異常
example:
127.0.0.1:6379> lset score1 0 1
OK
127.0.0.1:6379> lset score2 0 1
OK
在索引前/后插入元素
linsert key before|after pivot value:在pivot元素前或者后插入value這個元素
example:
127.0.0.1:6379> linsert score1 before 3 aaa
(integer) 3
127.0.0.1:6379> lrange score1 0 -1
1) "1"
2) "aaa"
3) "3"
127.0.0.1:6379> linsert score1 after 3 bbb
(integer) 4
127.0.0.1:6379> lrange score1 0 -1
1) "1"
2) "aaa"
3) "3"
4) "bbb"
rpoplpush resource destination:將鏈表中的尾部元素彈出並添加到頭部。[循環操作]
example:
127.0.0.1:6379> lrange score1 0 -1
1) "1"
2) "aaa"
3) "3"
127.0.0.1:6379> lrange score2 0 -1
1) "bbb"
2) "1"
3) "4"
127.0.0.1:6379> rpoplpush score1 score2
"3"
127.0.0.1:6379> lrange score1 0 -1
1) "1"
2) "aaa"
127.0.0.1:6379> lrange score2 0 -1
1) "3"
2) "bbb"
3) "1"
4) "4"
4、Redis-set
賦值
sadd key value[value1 value2...]:向set中添加元素,如果該key的值已有則不會重復添加
example:
127.0.0.1:6379> sadd abc 1 2 3 4
(integer) 4
srem key member[member1 member2...]:刪除set中指定的成員
example:
127.0.0.1:6379> srem abc 1 3
(integer) 2
取值
smembers key:獲取set中所有的成員
example:
127.0.0.1:6379> smembers abc
1) "2"
2) "4"
sismember key member:判斷參數中指定的成員是否在該set中,1表示存在,0表示不存在或者該key本身就不存在(無論集合中有多少元素都可以極速的返回結果)
example:
127.0.0.1:6379> sismember abc 2
(integer) 1
127.0.0.1:6379> sismember abc 3
(integer) 0
刪值
集合運算
差集運算
sdiff key1 key2...:返回key1與key2中相差的成員,而且與key的順序有關,即返回差集
example:
127.0.0.1:6379> sadd set1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd set2 3 4 5 6 7
(integer) 5
127.0.0.1:6379> sdiff set1 set2
1) "1"
2) "2"
127.0.0.1:6379> sdiff set2 set1
1) "6"
2) "7"
交集運算
sinter key1 key2...:返回交集
example:
127.0.0.1:6379> sinter set1 set2
1) "3"
2) "4"
3) "5"
並集運算
sunion key1 key2...:返回並集
example:
127.0.0.1:6379> sunion set1 set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
擴展命令
scard key:獲取set中成員的數量
example:
127.0.0.1:6379> scard set1
(integer) 5
srandmember key:隨機返回set中的一個成員
example:
127.0.0.1:6379> srandmember set1
"1"
127.0.0.1:6379> srandmember set1
"5"
127.0.0.1:6379> srandmember set1
"3"
sdiffstore destination key1 key2...:將key1 key2...相差的成員存儲在destination上
example:
127.0.0.1:6379> sdiffstore set3 set1 set2
(integer) 2
127.0.0.1:6379> smembers set3
1) "1"
2) "2"
sinterstore destination key[key...]:將返回的交集存儲在destination上
example:
127.0.0.1:6379> sinterstore set4 set1 set2
(integer) 3
127.0.0.1:6379> smembers set4
1) "3"
2) "4"
3) "5"
5、Redis-sortedset
賦值
zadd key score member score2 member2...:將所有成員以及該成員的分數存放到sorted-set中。如果該元素已經存在則會用新的分數代替原有的分數,返回值是新加入到集合中的元素個數,不包含之前已經存在的元素。
example:
127.0.0.1:6379> zadd list 50 xiaoming 100 xiaohong 200 xiaozhang
(integer) 3
取值
zscore key member:返回指定成員的分數
example:
127.0.0.1:6379> zscore list xiaohong
"100"
zcard key:獲取集合中的成員數量
example:
127.0.0.1:6379> zcard list
(integer) 3
范圍查詢
zrange key start end[withscores]:獲取集合中腳標為start-end的成員,[withscores]參數表明返回的成員包含其分數(分數從小到大排序)
example:
127.0.0.1:6379> zrange list 0 -1
1) "xiaoming"
2) "xiaohong"
3) "xiaozhang"
127.0.0.1:6379> zrange list 0 -1 withscores
1) "xiaoming"
2) "50"
3) "xiaohong"
4) "100"
5) "xiaozhang"
6) "200"
zrevrange key start end[withscores]:獲取集合中腳標為start-end的成員,[withscores]參數表明返回的成員包含其分數(分數從大到小排序)
example:
127.0.0.1:6379> zrevrange list 0 -1
1) "xiaozhang"
2) "xiaohong"
3) "xiaoming"
127.0.0.1:6379> zrevrange list 0 -1 withscores
1) "xiaozhang"
2) "200"
3) "xiaohong"
4) "100"
5) "xiaoming"
6) "50"
刪值
zrem key member[member...]:移除集合中指定的成員,可以指定多個成員
example:
127.0.0.1:6379> zrem list xiaozhang
(integer) 1
zremrangebyrank key start stop:按照排名范圍刪除元素
example:
127.0.0.1:6379> zremrangebyrank list 0 1
(integer) 2
zremrangebyscore key min max:按照分數范圍刪除元素
example:
127.0.0.1:6379> zremrangebyscore list 50 120
(integer) 2
擴展命令
zrangebyscore key min max [withscores][LIMIT offset count]:返回分數在[min,max]的成員並按照分數從低到高排序。[withscores]:顯示分數;[LIMIT offset count]:offset,表明從腳標為offset的元素開始並返回count個成員
example:
127.0.0.1:6379> zrangebyscore list 50 120 withscores limit 0 2
1) "xiaoming"
2) "50"
3) "xiaohong"
4) "100"
zincrby key increment member:設置指定成員的增加的分數,返回值是更改后的分數
example:
127.0.0.1:6379> zincrby list 30 xiaoming
"80"
zcount key min max:獲取分數在[min,max]之間的成員
example:
127.0.0.1:6379> zcount list 80 120
(integer) 2
zrank key member:返回成員在集合中的排名(索引從小到大)
example:
127.0.0.1:6379> zrank list xiaohong
(integer) 1
zrevrank key member:返回成員在集合中的排名。(索引從大到小)
example:
127.0.0.1:6379> zrevrank list xiaozhang
(integer) 0
6、通用Redis命令【重點】
keys pattern:獲取所有與pattern匹配的key,返回所有與該key匹配的keys。*表示任意一個或者多個字符
通配符:
-
*表示任意0個或者多個字符
-
?表示任意一個字符
exits key:判斷該key是否存在,1表示存在,0表示不存在
example:
127.0.0.1:6379> exists username
(integer) 1
127.0.0.1:6379> exists admin
(integer) 0
rename key newkey:為當前的key重命名
127.0.0.1:6379> rename username user
OK
127.0.0.1:6379> keys *
1) "list"
2) "abc"
3) "set1"
4) "information"
5) "set2"
6) "age"
7) "score2"
8) "set4"
9) "score1"
10) "set3"
11) "user"
type key:獲取指定的key的值類型,該命令將以字符串的格式返回。返回的字符串為string、list、set、hash和zset,
如果key不存在返回none
example:
127.0.0.1:6379> type user
string
127.0.0.1:6379> type list
zset
expire key:設置過期時間,單位:秒 如果某個key過期,redis會將其刪除
example:
127.0.0.1:6379> expire abc 10
(integer) 1
127.0.0.1:6379> keys *
1) "list"
2) "set1"
3) "information"
4) "set2"
5) "age"
6) "score2"
7) "set4"
8) "score1"
9) "set3"
10) "user"
ttl key:獲取該key所剩的超時時間,如果沒有設置超時時間,返回-1.如果返回-2表示超時不存在。
example:
127.0.0.1:6379> expire user 10
(integer) 1
127.0.0.1:6379> ttl user
(integer) 3
127.0.0.1:6379> ttl user
(integer) -2
127.0.0.1:6379> keys *
1) "list"
2) "set1"
3) "information"
4) "set2"
5) "age"
6) "score2"
7) "set4"
8) "score1"
9) "set3"
127.0.0.1:6379> ttl information
(integer) -1
7、Redis其他特性
消息訂閱與發布
subscribe channel:訂閱頻道
example:
127.0.0.1:6379> subscribe mychat
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "mychat"
3) (integer) 1
psubscribe channel*:批量訂閱頻道
example:
127.0.0.1:6379> psubscribe s*
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "s*"
3) (integer) 1
publish channel content:在指定的頻道中發布消息
example:
127.0.0.1:6379> publish mychat 'today is a newday'
(integer) 1
多數據庫
傳統數據庫如MySQL數據庫可以自己用語句自定義創建,我們可以通過create database xxxx進行創建。Redis 也是有數據庫的,不過Redis已經提前創建好了。在redis默認有十六個數據庫,0,1,2....15,在radis上所作的所有數據操作,都是默認在0號數據庫上操作,數據庫與數據庫之間是不能共享鍵值對的。我們可以把Redis數據庫理解為一個map集合。
切換數據庫
select 數據庫名:切換數據庫
example:
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> select 15
OK
127.0.0.1:6379[15]> select 16
(error) ERR DB index is out of range
數據庫的移植
move newkey 數據庫名:將當前數據庫的key移植到指定的數據庫中
example:
127.0.0.1:6379> keys *
1) "list"
2) "set1"
3) "information"
4) "set2"
5) "age"
6) "score2"
7) "set4"
8) "score1"
9) "set3"
127.0.0.1:6379> move information 1
(integer) 1
127.0.0.1:6379> keys *
1) "list"
2) "set1"
3) "set2"
4) "age"
5) "score2"
6) "set4"
7) "score1"
8) "set3"
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> keys *
1) "information"
數據庫清空
flushdb 刪除當前數據庫中的所有key
flushall 刪除所有數據庫中的所有key
服務器命令
ping 測試連接是否存活
example:
127.0.0.1:6379> ping
PONG
echo 在命令行打印一些內容
example:
127.0.0.1:6379> echo hehe
"hehe"
quit/Ctrl+C 退出客戶端
example:
127.0.0.1:6379> quit
dbsize 返回當前數據庫中的key的數目
example:
127.0.0.1:6379> dbsize
(integer) 8
info 獲取服務器的信息和統計
example:
127.0.0.1:6379> info
# Server
redis_version:4.9.103
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:d727e4f6fe88cefd
redis_mode:standalone
......
......
8、Redis持久化策略
RDB策略
RDB是redis的默認持久化機制,相當於照快照,保存的是一種狀態
優點:
-
快照速度極快,還原數據速度極快
-
適用於災難備份
缺點:
- 小內存機器不適合使用
RDB機制符合要求就會照快照(隨時隨地啟動),會占用一定的系統資源(突然的)很可能內存不足直接宕機。(宕機后,服務器會關閉,屬於非正常關閉,數據會丟失)
RDB機制適用於內存比較充裕的計算機
RDB是何時進行照快照?
-
服務器正常關閉時,會照一次快照
-
key滿足一定條件時,會照一次快照
-
-
save 900 1#每900秒至少有1個key發生變化,則dump內存快照
-
save 300 10#每300秒至少有10個key發生變化,則dump內存快照
-
save 60 10000#每60秒至少有10000個key發生變化,則dump內存快照
-
AOF策略
AOF策略是一種使用日志功能保存數據操作的機制,默認AOF機制關閉的,它的操作只會保存導致key變化的語句
優點:
- 持續性占用極少量的內存資源
缺點:
-
日志文件會特別大,不適用於災難恢復
-
恢復效率遠遠低於RDB
AOF機制適用於內存比較小的計算機
AOF是如何進行數據備份的呢?
-
每秒同步:每秒進行一次AOF保存數據,安全性低,比較節省系統資源
-
每修改同步:只要有key變化語句,就進行AOF保存數據,比較安全,但是這樣做極為浪費系統資源,降低效率
-
不同步:不進行任何持久化操作,這種配置不安全
AOF的配置
-
always #每秒有數據修改發生時都會寫入AOF文件
-
everysec #每秒同步一次,該策略為AOF的缺省策略
-
no #從不同步。高效但是數據不會被持久化
開啟AOF機制的方法
-
在redis.config文件中用:/aof找到對應的段落
-
將appendonly no改成appendonly yes
-
再修改其中一段成appendfsync always即可