此次咱們來講說咱們的redis,在咱們的redis的認知裏,最熟悉的就是用redis做爲緩存使用,還有咱們的分佈式session,其實還有不少redis的使用,還有redis的哨兵模式等等。linux
Redis(全稱:Remote Dictionary Server 遠程字典服務)是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。從2010年3月15日起,Redis的開發工做由VMware主持。從2013年5月開始,Redis的開發由Pivotal贊助。(百度百科)redis
安裝(linux爲例講解):數據庫
1.先安裝一下C語言的包,redis的底層是用C來寫的,若是不安裝可能安裝的時候會報錯的。輸入$ yum install gccjson
2.得到redis資源,輸入 $ wget http://download.redis.io/releases/redis-5.0.5.tar.gz小程序
3.開始安裝,輸入如下命令便可vim
$ tar -zxvf redis-5.0.5.tar.gz;
緩存
$ cd redis-5.0.5;
網絡
$ make
session
4.修改配置,直接輸入vim redis.conf,而後跳轉到136行(差很少就是136行,版本不一樣文件可能存在差別),daemonize no設置爲daemonize yes,數據結構
5.啓動,輸入./src/redis-server redis.conf 便可啓動了,輸入ps -ef|grep redis能夠看到redis是否啓動成功。
6.輸入./src/redis-cli 便可進入客戶端,quit退出。
官網有如何安裝的教程這裏就不在繼續贅述了。
redis的數據結構:
咱們都知道redis是鍵值對的形式來存儲數據的,其實內部還有幾種結構的,也是咱們常見經常使用的結構,這裏來詳細說一下。
咱們接下來會圍繞這五種數據結構來展開去講。
結構與常見命令場景
String常見操做
SET KEY VALUE //存入單個字符串鍵值對,最多見不過了,單值緩存,就不說啦。
MSET KEY VALUE//批量寫入字符串,通常來存對象。看下實例
這裏有一張職員表,內容以下
只存了姓名和年齡兩個字段,之前咱們的方式都是設置一個key,而後把姓名和年齡轉爲json而後再存儲對吧。
咱們來看一下咱們的MSet命令是如何使用並存儲的。
mset user:1:name zhang user:1:age 1
也就是說咱們一口氣直接把user表內id爲1的對象都存在了redis裏,而後咱們用mget user:1:name user:1:age。就能夠一次性取出來了。
SETNX //存入一個不存在的字符串鍵值對,咱們來看一下實例。最簡單的分佈式鎖就看能夠用他來實現。
127.0.0.1:6379> setnx lock:user true
(integer) 1
127.0.0.1:6379> setnx lock:user true
(integer) 0
就是說只容許一次的寫入,寫入成功纔會返回1,不然是0,咱們的線程爭搶就看誰優先寫入啦。
GET KEY//取得一個鍵對應的字符串,上文提到過 ,再也不贅述
MGET KEY//批量得到鍵對應的字符串,上文提到過 ,再也不贅述
EXPIRE KEY SECONDS //設置一個鍵的過時時間,單位是秒
127.0.0.1:6379> expire lock:user 1
(integer) 1
127.0.0.1:6379> get lock:user
(nil)
原子加減
INCR key //將key中存儲的數字值加1,通常用在新聞點贊計數操做 incr {文章:id}
127.0.0.1:6379> incr article:xiaocai
(integer) 1
127.0.0.1:6379> incr article:xiaocai
(integer) 2
127.0.0.1:6379> incr article:xiaocai
(integer) 3
127.0.0.1:6379> incr article:xiaocai
(integer) 4
DECR key //將key中存儲的數字值減1,通常用在新聞點贊計數操做
INCRBY KEY increment //將key所存儲的值加上increment
DECRBY key decrement //將key所存儲的值減去decrement
哈希Hash常見操做
hash結構和咱們的String有些不一樣,本來String是一個key對應一個value,而咱們的hash是一個redis_key,對應一組值,內部還有hash_key對應咱們的hash_value。可是用法幾乎是一致
hset key hash_key hash_value //存儲一個hash表的key的鍵值對
127.0.0.1:6379> hset user 1:name zhao
(integer) 0
127.0.0.1:6379> hget user 1:name
"zhao"
hsetnx key hash_key hash_value //存儲一個不存在的hash表的key的鍵值對
127.0.0.1:6379> hsetnx lock user:locak true
(integer) 1
127.0.0.1:6379> hsetnx lock user:locak true
(integer) 0
hmset key hash_key hash_value //存儲一個hash表的多個key的鍵值對
127.0.0.1:6379> hmset user 1:name zhoao 1:age 11
OK
127.0.0.1:6379> hmget user 1:name 1:age
1) "zhoao"
2) "11"
hget key hash_key //獲取哈希表key對應的多個hash鍵值
hdel key hash_key //刪除哈希表key中的hash鍵值對
hlen key //返回全部哈希表key中該鍵的數量
127.0.0.1:6379> hlen user
(integer) 2
hgetall key //返回全部哈希表key中全部鍵的鍵值對
127.0.0.1:6379> hgetall user
1) "1:name"
2) "zhoao"
3) "1:age"
4) "11"
hash哈希的有點在於,對於同類的數據更好的整合在了一塊兒,方便數據的管理,相比String操做消耗的內存與cpu更小(之後會詳細說明爲何小),空間佔用也是比String要小的,但在集羣的架構下不適合大規模的使用。
列表常見操做
lpush key value //將一個或者多個值value插入到key列表的最左邊left
127.0.0.1:6379> lpush liredis a
(integer) 1
127.0.0.1:6379> lpush liredis b
(integer) 2
127.0.0.1:6379> lpush liredis c
(integer) 3
rpush key value //將一個或者多個值value插入到key列表的最右邊right
127.0.0.1:6379> rpush liredis 1
(integer) 4
127.0.0.1:6379> rpush liredis 2
(integer) 5
127.0.0.1:6379> rpush liredis 3
(integer) 6
lpop key //移除並返回對應key的頭元素(最左邊的元素)
127.0.0.1:6379> lpop liredis
"c"
rpop key //移除並返回對應key的尾元素(最右邊的元素)
127.0.0.1:6379> rpop liredis
"3"
lrange key start stop //返回列表key中start到stop的區間元素,須要注意的是角標是從0開始的,start和stop都包含在內的,不如咱們輸入 lrange redis_key 0 2 ,則表示取得第0,1,2三個元素。
127.0.0.1:6379> lrange liredis 1 2
1) "a"
2) "1"
blpop key timeout //從列表key的表頭(最左側)彈出第一個元素,若隊列中沒有元素,阻塞等待timeout秒,若是timeout=0,一直等待
127.0.0.1:6379> blpop liredis 1
1) "liredis"
2) "b"
127.0.0.1:6379> blpop liredis 1
1) "liredis"
2) "a"
127.0.0.1:6379> blpop liredis 1
1) "liredis"
2) "1"
127.0.0.1:6379> blpop liredis 1
1) "liredis"
2) "2"
127.0.0.1:6379> blpop liredis 1
(nil)
(1.04s)
brpop key timeout //從列表key的表尾(最右側)彈出末尾元素,若隊列中沒有元素,阻塞等待timeout秒,若是timeout=0,一直等待
更好的理解咱們的列表命令,咱們能夠從數據結構的角度來講一下。
棧:先進先出,也就是咱們的Lpush+lpop,或者rpush+rpop就能夠實現的。
隊列:先進後出,也就是咱們的Lpush+rpop,或者rpush+lpop就能夠實現的。
阻塞隊列:lpush+brpop也就能夠實現啦。
set集合常見操做
sadd key member //往集合key中存入元素,元素存在則忽略
127.0.0.1:6379> sadd setredis 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd setredis 1 2
(integer) 0
srem key member //從集合key中刪除元素
127.0.0.1:6379> srem setredis a
(integer) 0
127.0.0.1:6379> srem setredis 1
(integer) 1
smembers key //獲取集合中的全部元素
127.0.0.1:6379> smembers setredis
1) "2"
2) "3"
3) "4"
4) "5"
scard key //獲取集合key中的元素個數
127.0.0.1:6379> scard setredis
(integer) 4
sismember key member //判斷member元素是否存在於集合key中
127.0.0.1:6379> sismember setredis a
(integer) 0
127.0.0.1:6379> sismember setredis 2
(integer) 1
srandmember key count //從集合key中選出count個元素,元素不從key中刪除
127.0.0.1:6379> srandmember setredis 2
1) "5"
2) "4"
spop key count //從集合key中選出count個元素,元素從key中刪除,抽獎小程序可使用這個。
127.0.0.1:6379> spop setredis 1
1) "4"
127.0.0.1:6379> smembers setredis
1) "2"
2) "3"
3) "5"
集合的運算,咱們在高中數學第一節課的時候就講過集合(咱們當時高中第一節講的就是集合),不知道你們還記得交集並集補集都是什麼意思嗎?
sinter keyA keyB //集合keyA和集合B的交集,就是求既在集合A也在集合B內的元素
127.0.0.1:6379> sadd setA 1 2 3 4 5 6
(integer) 6
127.0.0.1:6379> sadd setB 5 6 7 9 10
(integer) 5
127.0.0.1:6379> sinter setA setB
1) "5"
2) "6"
sinterstore destination keyA keyB //將交集的結果存在新的集合destination中
127.0.0.1:6379> SINTERSTORE newset setA setB
(integer) 2
127.0.0.1:6379> smembers newset
1) "5"
2) "6"
sunion keyA keyB //獲得集合A和集合B的並集結果
127.0.0.1:6379> SUNION setA setB
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "7"
8) "9"
9) "10"
sunionstore destination keyA keyB //將並集的結果存在新的集合destination中
sdiff keyA keyB //求集合A對於集合B的差集,也就是{A}-{B},更通俗一點說就是存在於集合A的,可是不存在於集合B的元素。
127.0.0.1:6379> smembers setA
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> smembers setB
1) "5"
2) "6"
3) "7"
4) "9"
5) "10"
127.0.0.1:6379> sdiff setA setB
1) "1"
2) "2"
3) "3"
4) "4"
sdiffstore destination keyA keyB //將差集的結果存在新的集合destination中
擴展:若是咱們是sdiff keyA keyB keyC //這裏就表示{A}-{B}-{C}。不要琢磨什麼這是A對於B和C並集的差集...亂不亂,本身都懵圈的。
集合A:[1,2,3,4,5,6]
集合B:[2,3,4]
集合C:[5,7,9]
這時咱們輸入sdiff keyA keyB keyC他的返回應該是[1,6]。由於{A}-{B}爲{1,5,6},在用這個集合去掉C包含的元素,也就是5,最終獲得集合[1,6]
有序zSet常見操做
zadd key score member score member //往有序集合key中加入帶score分值的元素
127.0.0.1:6379> zadd zsetredis 1 zhaor 2 qian
(integer) 2
zrem key member //從有序集合key中刪除元素
127.0.0.1:6379> zrem zsetredis zhaor
(integer) 1
zscore key member //返回有序集合key中元素member的分值
127.0.0.1:6379> zscore zsetredis qian
"2"
zincrby key increment menber //爲有序集合key中元素member的分值加上increment數值
127.0.0.1:6379> ZINCRBY zsetredis 10 qian
"12"
ZCARD key //返回有序集合key中的元素個數
127.0.0.1:6379> ZCARD zsetredis
(integer) 2
zrange key start stop withscores//正序獲取有序集合內從 start到stop下標的元素,加了withscores展現分值
127.0.0.1:6379> zrange zsetredis 0 999
1) "zhao"
2) "qian"
zrevrange key start stop withscores//倒序獲取有序集合內從 start到stop下標的元素,加了withscores展現分值
127.0.0.1:6379> ZREVRANGE zsetredis 0 999
1) "qian"
2) "zhao"
正序倒序都是按照分值來排序的
zSet運算
zunioonstore destkey numkeys keyA keyB //求集合A和集合B的並集
127.0.0.1:6379> ZUNIONSTORE newzset 2 zsetA zsetb
(integer) 4
127.0.0.1:6379> ZRANGE newzset 0 1111
1) "wuliu"
2) "zhaogsan"
3) "wangwu"
4) "lisi"
zinterstore destkey numkeys KeyA keyB //求集合A和集合B的交集,只看元素,不看分值。
127.0.0.1:6379> ZINTERSTORE newset 2 zsetA zsetb
(integer) 1
127.0.0.1:6379> zrange newset 0 1111
1) "lisi"
最進弄了一個公衆號,小菜技術,歡迎你們的加入