• Redis和Memcached相似,也屬於k-v數據存儲php
• Redis官網redis.io, 當前最新穩定版4.0.1html
• Redis是一個開源的使用ANSI C語言編寫、遵照BSD協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value數據庫,並提供多種語言的API。mysql
它一般被稱爲數據結構服務器,由於值(value)能夠是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等類型。linux
•支持更多value類型,除了和string外,還支持hash、lists(鏈表)、sets(集合)和sorted sets(有序集合)git
• 經常使用存儲類型 : string、hash、lists(鏈表)、sets(集合)、sorted sets(有序集合)github
• redis使用了兩種文件格式:全量數據(RDB)和增量請求(aof)。全量數據格式是把內存中的數據寫入磁盤,便於下次讀取文件進行加載。增量請求文件則是把內存中的數據序列化爲操做請求,用於讀取文件進行replay獲得數據,這種相似於mysql binlog。全量數據搞過一次以後,全量數據能夠刪除掉。面試
• redis的存儲分爲內存存儲、磁盤存儲和log文件三部分 redis
• 下載最新穩定版sql
• cd /usr/local/src/數據庫
• wget http://download.redis.io/releases/redis-4.0.1.tar.gz
• cd redis-4.0.1
• make && make install
• cp redis.conf /etc/redis.conf
• vim /etc/redis.conf //修改以下配置
daemonize yes
logfile "/var/log/redis.log"
dir /data/redis_data/
appendonly yes
• mkdir /data/redis_data
• sysctl vm.overcommit_memory=1
• echo never > /sys/kernel/mm/transparent_hugepage/enabled
• redis-server /etc/redis.conf
實例:
[root@localhost 0]# cd /usr/local/src/ [root@localhost src]# wget http://download.redis.io/releases/redis-4.0.1.tar.gz [root@localhost src]# tar zxvf redis-4.0.1.tar.gz [root@localhost src]# cd redis-4.0.1 編譯 [root@localhost redis-4.0.1]# make && make install [root@localhost redis-4.0.1]# echo $? #檢測上一步是否正確 0 測試redis是否正常運行 [root@localhost 01]# redis- #敲兩次回車,自動查看相關命令 redis-benchmark redis-check-rdb redis-sentinel redis-check-aof redis-cli redis-server [root@localhost 01]# which redis-cli #查看安裝位置 /usr/local/bin/redis-cli 把配置文件拷貝到/etc/redis.conf文件下 [root@localhost 01]# cp redis.conf /etc/redis.conf [root@localhost 01]# vim /etc/redis.conf 把daemonize no設置成daemonize yes #該成yes以後,就在後臺啓動 把日誌的文件logfile 「」修改爲logfile "/var/log/redis.log" #指定日誌文件 把dir ./ 修改爲dir /data/redis # dir是指定dump文件的位置 appendonly no 修改爲 appendonly yes #做用開啓ouf日誌,開啓後,會在dir指定的目錄中生成appendfilename aof文件 建立一個新的文件 [root@localhost 01]# mkdir /data/redis [root@localhost 0]# redis-server /etc/redis.conf #啓動redis服務 [root@localhost 01]# ps aux |grep redis root 88045 0.1 0.2 145296 2192 ? Ssl 15:56 0:00 redis-server 127.0.0.1:6379 root 88059 0.0 0.0 112720 968 pts/0 R+ 15:57 0:00 grep --color=auto redis [root@localhost 01]# less /var/log/redis.log #查看日誌 [root@localhost 01]# sysctl vm.overcommit_memory=1 vm.overcommit_memory = 1 [root@localhost 01]# echo never > /sys/kernel/mm/transparent_hugepage/enabled [root@localhost 01]# vim /etc/rc.local touch /var/lock/subsys/local #下面是添加的內容 sysctl vm.overcommit_memory=1 echo never > /sys/kernel/mm/transparent_hugepage/enabled
• Redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)
• RDB,簡而言之,就是在不一樣的時間點,將redis存儲的數據生成快照並存儲到磁盤等介質上。若是存儲到內存中,重啓以後就會數據就會消失。
• AOF,則是換了一個角度來實現持久化,那就是將redis執行過的全部寫指令記錄下來,在下次redis從新啓動時,只要把這些寫指令從前到後再重複執行一遍,就能夠實現數據恢復了。
• 其實RDB和AOF兩種方式也能夠同時使用,在這種狀況下,若是redis重啓的話,則會優先採用AOF方式來進行數據恢復,這是由於AOF方式的數據恢復完整度更高。數據和日誌會先存儲到內存中,而後同步到磁盤中。
• 若是你沒有數據持久化的需求,也徹底能夠關閉RDB和AOF方式,這樣的話,redis將變成一個純內存數據庫,就像memcache同樣。
save 900 1 #表示每15分鐘且至少有1個key改變,就觸發一次持久化
save 300 10 #表示每5分鐘且至少有10個key改變,就觸發一次持久化
save 60 10000 #表示每60秒至少有10000個key改變,就觸發一次持久
save 「」 #這樣能夠禁用rdb持久化
appendonly yes #若是是yes,則開啓aof持久化
appendfilename 「appendonly.aof」 # 指定aof文件名字
appendfsync everysec #指定fsync()調用模式,有三種no(不調用fsync),always(每次寫都會調用fsync),everysec(每秒鐘調用一次fsync)。第一種最快,第二種數據最安全,但性能會差一些,第三種爲這種方案,默認爲第三種。
求差集的時候須要將數據多的鍵值放在前面。。。不然結果是空集
set1至關於set2的子集,因此set1對set2求差集結果確定是空集
• string爲最簡單的類型,與Memcached同樣的類型,一個key對應一個value,其支持的操做與Memcached的操做相似,它的功能更豐富。設置能夠存二進制的對象。
• 示例:
# redis-cli
127.0.0.1:6379> set mykey "aminglinux.com"
OK
127.0.0.1:6379> get mykey
"aminglinux.com"
127.0.0.1:6379> mset key1 1 key2 a key3 c #同時設置多個鍵值
127.0.0.1:6379> mget key1 key2 key3 #同時查看多個鍵值
1) "1"
2) "a"
3) "c"
實例
[root@localhost 0]# redis-cli 127.0.0.1:6379> set mykey 123 100 (error) ERR syntax error 127.0.0.1:6379> set mykey "123" OK 127.0.0.1:6379> get mykey "123" 127.0.0.1:6379> MSET k1 1 k2 2 k3 a OK 127.0.0.1:6379> mget k1 mykey 1) "1" 2) "123"
• list是一個鏈表結構,主要功能是push、pop、獲取一個範圍的全部值等等。操做中key理解爲鏈表的名字。
• 使用 list 結構,咱們能夠輕鬆地實現最新消息排行等功能(好比新浪微博的 TimeLine )。list 的另外一個應用就是消息隊列,能夠利用 list 的 push操做,將任務存在 list 中,而後工做線程再用pop操做將任務取出進行執行。
• 示例:
• # redis-cli
127.0.0.1:6379> LPUSH list1 "aminglinux"
127.0.0.1:6379> LPUSH list1 "1 2 3"
127.0.0.1:6379> LPUSH list1 "aaa bbb「
127.0.0.1:6379> LRANGE list1 0 -1 #查看list的值
1) "aaa bbb"
2) "1 2 3"
3) "aminglinux「
127.0.0.1:6379> LPOP list1 #取出數值
實例:
[root@localhost 01]# redis-cli 127.0.0.1:6379> LPUSH list1 "aminglinux" 127.0.0.1:6379> LPUSH list1 "1 2 3" 127.0.0.1:6379> LPUSH list1 "aaa bbb「 127.0.0.1:6379> LRANGE list1 0 -1 #查看list的值 1) "aaa bbb" 2) "1 2 3" 3) "aminglinux「 127.0.0.1:6379> LPOP list1
• set是集合,和咱們數學中的集合概念類似,對集合的操做有添加刪除元素,有對多個集合求交併差等操做。操做中key理解爲集合的名字。好比在微博應用中,能夠將一個用戶全部的關注人存在一個集合中,將其全部粉絲存在一個集合。由於 Redis 很是人性化的爲集合提供了求交集、並集、差集等操做,那麼就能夠很是方便的實現如共同關注、共同喜愛、二度好友等功能,對上面的全部集合操做,你還可使用不一樣的命令選擇將結果返回給客戶端仍是存集到一個新的集合中。
• set示例
127.0.0.1:6379> SADD set1 a
127.0.0.1:6379> SADD set1 b
127.0.0.1:6379> SADD set1 c
127.0.0.1:6379> SADD set1 d
127.0.0.1:6379> SMEMBERS set1
1) "d"
2) "b"
3) "a"
4) "c"
127.0.0.1:6379> SREM set1 c//刪除元素
127.0.0.1:6379> SADD set2 a 2 b
127.0.0.1:6379> SINTER set1 set2 //交集
127.0.0.1:6379> SUNION set1 set2 //並集
127.0.0.1:6379> SDIFF set1 set2 //差集
實例
[root@localhost 01]# redis-cli 127.0.0.1:6379> SADD set1 a (integer) 1 127.0.0.1:6379> SADD set1 b (integer) 1 127.0.0.1:6379> SADD set1 c (integer) 1 127.0.0.1:6379> SADD set1 d (integer) 1 127.0.0.1:6379> SMEMBERS set1 @#查看集合中的全部元素 1) "d" 2) "c" 3) "a" 4) "b" 127.0.0.1:6379> sadd set2 a (integer) 1 127.0.0.1:6379> sadd set2 2 (integer) 1 127.0.0.1:6379> sadd set2 3 (integer) 1 127.0.0.1:6379> sadd set2 c (integer) 1 127.0.0.1:6379> SMEMBERS set2 1) "c" 2) "2" 3) "a" 4) "3" 127.0.0.1:6379> SUNION set1 set2 #查看並值 1) "2" 2) "d" 3) "c" 4) "a" 5) "b" 6) "3" 127.0.0.1:6379> SINTER set1 set2 #查看交集 1) "c" 2) "a" 127.0.0.1:6379> SDIFF set1 set2 #求差值 1) "d" 2) "b" 127.0.0.1:6379> SREM set1 c #刪除set1中c (integer) 1 127.0.0.1:6379> SMEMBERS set1 #查看是否刪除成功 1) "d" 2) "a" 3) "b"
• sorted set是有序集合,它比set多了一個權重參數score,使得集合中的元素可以按 score 進行有序排列,好比一個存儲全班同窗成績的 Sorted Sets,其集合 value 能夠是同窗的學號,而 score 就能夠是其考試得分,這樣在數據插入集合的時候,就已經進行了自然的排序。
127.0.0.1:6379> ZADD set3 12 abc
127.0.0.1:6379> ZADD set3 2 "cde 123"
127.0.0.1:6379> ZADD set3 24 "123-aaa"
127.0.0.1:6379> ZADD set3 4 "a123a"
127.0.0.1:6379> ZRANGE set3 0 -1
1) "cde 123"
2) "a123a"
3) "abc"
4) "123-aaa"
倒序
127.0.0.1:6379> ZREVRANGE set3 0 -1
1) "123-aaa"
2) "abc"
3) "a123a"
4) "cde 123"
實例:
有序排列
自然排序 127.0.0.1:6379> ZADD set3 12 abc (integer) 1 127.0.0.1:6379> ZADD set3 2 "cde 123" (integer) 1 127.0.0.1:6379> ZADD set3 24 "aming" (integer) 1 127.0.0.1:6379> ZADD set3 4 "aminglinux" (integer) 1 127.0.0.1:6379> ZADD set3 0 -1 (integer) 1 127.0.0.1:6379> ZRANGE set3 0 -1 #排列的順序是0 ,2,4,12,24 1) "-1" 2) "cde 123" 3) "aminglinux" 4) "abc" 5) "aming" 倒序 ----- 最大的在前面, 127.0.0.1:6379> ZREVRANGE set3 0 -1 1) "aming" 2) "abc" 3) "aminglinux" 4) "cde 123" 5) "-1"
• 在 Memcached 中,咱們常常將一些結構化的信息打包成 hashmap,在客戶端序列化後存儲爲一個字符串的值(通常是 JSON 格式),好比用戶的暱稱、年齡、性別、積分等。
• 示例
127.0.0.1:6379> hset hash1 name aming #設置哈希值
127.0.0.1:6379> hget hash1 name
"aming"
127.0.0.1:6379> hset hash1 age 30
127.0.0.1:6379> hget hash1 age
"30"
127.0.0.1:6379> hgetall hash1 #獲取所有的哈希值
1) "name"
2) "aming"
3) "age"
4) "30"
實例:
添加元素
127.0.0.1:6379> HSET hash1 name aming #設置哈希值 (integer) 1 127.0.0.1:6379> HSET hash1 age 30 (integer) 1 127.0.0.1:6379> HSET hash1 name (error) ERR wrong number of arguments for 'hset' command 127.0.0.1:6379> HGET hash1 name #獲取部分哈希值 "aming" 127.0.0.1:6379> HGET hash1 jobs (nil) 127.0.0.1:6379> HGET hash1 job (nil) 127.0.0.1:6379> hgetall hash1 #獲取所有哈希值 1) "name" 2) "aming" 3) "age" 4) "30" 127.0.0.1:6379>
• set key1 aminglinux #若是以前設置過一次KEY1,再次設置就會,覆蓋
• get key1
• set key1 aming //第二次賦值會覆蓋
• setnx key2 aaa //返回1 若是key2不存在直接建立key
• setnx key2 bbb //返回0,若是key2存在,返回0,不存在,返回1
• setex key3 10 1 //給key3設置過時時間爲10s,值爲1,若key已經存在,會覆蓋新的值
• mset k1 1 k2 a k3 c
• mget k1 k3 k2
• lpush lista a //從左側加入一個元素
• lpush lista b
• lrange lista 0 -1
• lpop lista //從左側取出第一個元素
• rpush lista 1 //從右側加入一個元素
• rpop lista //從右側取出第一個元素
面試的時候,可能會問一些redis持久化、集羣方面的問題。
實例:
127.0.0.1:6379> set key1 aming OK 127.0.0.1:6379> set key2 linux OK 127.0.0.1:6379> set key1 linux OK 127.0.0.1:6379> get key1 #再次設置會,覆蓋aming "linux" 127.0.0.1:6379> setnx key1 aaa (integer) 0 127.0.0.1:6379> get key1 "linux" 127.0.0.1:6379> setnx key3 aaa (integer) 1 127.0.0.1:6379> get key3 "aaa" 127.0.0.1:6379> set key3 aaa ex 10 #後面的10是過時時間10秒 OK 127.0.0.1:6379> get key3 #過10秒,再次查看key3的值,發現已經不存在了 (nil) 127.0.0.1:6379> set key3 aaa ex 100 #後面的100是過時時間100秒 OK 127.0.0.1:6379> get key3 #不到過時時間,能夠查看key3的值 "aaa" 127.0.0.1:6379> SETEX key3 1000 bbb # "bbb" //給key3設置過時時間爲10s,值爲1,若key已經存在,會覆蓋新的值 OK 127.0.0.1:6379> get key3 127.0.0.1:6379> LPUSH list2 aaa (integer) 1 127.0.0.1:6379> LPUSH list2 bbb (integer) 2 127.0.0.1:6379> LPUSH list2 (error) ERR wrong number of arguments for 'lpush' command 127.0.0.1:6379> LRANGE list2 0 -1 #排列順序是,後面設置值的放在前面 1) "-1" 2) "0" 3) "bbb" 4) "aaa" 127.0.0.1:6379> LPOP list2 #抓取的值,是後面的設置的值 "-1" 127.0.0.1:6379> LPUSH list2 ccc //從左側加入一個元素 (integer) 4 127.0.0.1:6379> LPUSH list2 ddd (integer) 5 127.0.0.1:6379> LPUSH list2 0 -1 (integer) 7 127.0.0.1:6379> LRANGE list2 0 -1 #從最小的值排列 1) "-1" 2) "0" 3) "ddd" 4) "ccc" 5) "0" 6) "bbb" 7) "aaa" 127.0.0.1:6379> RPOP list2 #抓取列表最底下的值,值取出來以後,其餘的就刪除掉 "aaa"
• linsert lista before 2 3 //在2的前面插入一個元素爲3
• lset lista 4 bbb //把第5個元素修改成bbb
• lindex lista 0 //查看第1個元素
• lindex lista 3 //查看第4個元素
• llen lista //查看鏈表中有幾個元素
• sadd seta aaa //向集合seta中放入元素
• smembers seta //查看集合中的全部元素
• srem seta aaa //刪除元素
• spop seta //隨機取出一個元素,刪除
• sdiff seta setb //求差集,以seta爲標準
• sdiffstore setc seta setb //求差集而且存儲,存儲到了setc裏
• sinter seta setb //求交集
• sinterstore setd seta setb //將交集存儲setd
• sunion seta setb //求並集
• sunionstore sete seta setb //求並集並存儲到sete
實例:
127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替換值 127.0.0.1:6379> LSET list2 1 11 #把第二個值,替換成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一個值,替換成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表裏第二個值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表裏面有幾個值 (integer) 9 127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替換值 127.0.0.1:6379> LSET list2 1 11 #把第二個值,替換成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一個值,替換成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表裏第二個值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表裏面有幾個值 (integer) 9 127.0.0.1:6379> LINSERT list2 before 1 3 (integer) -1 127.0.0.1:6379> LINSERT list2 before 0 1 (integer) 7 127.0.0.1:6379> LINSERT list2 before 2 3 (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER 2 aaa (integer) -1 127.0.0.1:6379> LINSERT list2 AFTER ccc aaa (integer) 8 127.0.0.1:6379> LINSERT list2 AFTER aaa bbb (integer) 9 127.0.0.1:6379> LRANGE list2 0 -1 1) "-1" 2) "1" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 替換值 127.0.0.1:6379> LSET list2 1 11 #把第二個值,替換成11 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 127.0.0.1:6379> LSET list2 0 123 #把第一個值,替換成123 OK 127.0.0.1:6379> LRANGE list2 0 -1 #查看替換的值 1) "123" 2) "11" 3) "0" 4) "ddd" 5) "ccc" 6) "aaa" 7) "bbb" 8) "0" 9) "bbb" 查看元素 127.0.0.1:6379> LINDEX list2 1 #查看list2列表裏第二個值 "11" 127.0.0.1:6379> LINDEX list2 0 "123" 127.0.0.1:6379> LLEN list2 #查看list2列表裏面有幾個值 (integer) 9 集合seta中放入元素 127.0.0.1:6379> sadd seta aaa (integer) 1 127.0.0.1:6379> sadd seta bbb (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "aaa" 2) "bbb" 127.0.0.1:6379> SPOP sete #取出值,sete,就變成空的了 "bbb" 127.0.0.1:6379> SMEMBERS sete (empty list or set) 求差集,以seta爲標準 127.0.0.1:6379> sadd seta aaa (integer) 0 127.0.0.1:6379> sadd seta bbb (integer) 0 127.0.0.1:6379> sadd seta cc (integer) 1 127.0.0.1:6379> sadd seta 111 (integer) 1 127.0.0.1:6379> sadd seta 222 (integer) 1 127.0.0.1:6379> sadd setb 111 (integer) 1 127.0.0.1:6379> sadd setb 222 (integer) 1 127.0.0.1:6379> SMEMBERS seta 1) "aaa" 2) "111" 3) "bbb" 4) "cc" 5) "222" 127.0.0.1:6379> SMEMBERS setb 1) "111" 2) "222" 127.0.0.1:6379> SDiFF seta setb #求差值,以第一個設置的seta爲比較值,把與setb相同的值去掉 1) "aaa" 2) "bbb" 3) "cc" 127.0.0.1:6379> SDiFF setb seta #求差值,以第一個設置的setb爲比較值,把與seta相同的值去掉 (empty list or set)
• sismember seta aaa //判斷一個元素是否屬於一個集合
• srandmember seta //隨機取出一個元素,但不刪除
• zadd zseta 11 123 //建立有序集合
• zrange zseta 0 -1 //顯示全部元素,按順序顯示
• zrange zseta 0 -1 withscores //能夠帶上分值
• zrem zseta 222 //刪除指定元素
• zrank zseta 222 //返回元素的索引值,索引值從0開始,按score正向排序
• zrevrank zseta 222 //同上,不一樣的是,按score反序排序
• zrevrange zseta 0 -1 反序顯示全部元素,並帶分值
• zcard zseta //返回集合中全部元素的個數
• zcount zseta 1 10 // 返回分值範圍1-10的元素個數
• zrangebyscore zseta 1 10 // 返回分值範圍1-10的元素
• zremrangebyrank zseta 0 2 //刪除索引範圍0-2的元素,按score正向排序
• zremrangebyscore zseta 1 10 //刪除分值範圍1-10的元素
實例:
判斷一個元素是否屬於一個集合 127.0.0.1:6379> SISMEMBER seta 1 (integer) 0 127.0.0.1:6379> SISMEMBER seta 111 (integer) 1 127.0.0.1:6379> SRANDMEMBER seta 隨機取出一個元素 "aaa" 127.0.0.1:6379> SRANDMEMBER seta 2 隨機取出2個元素 1) "222" 2) "bbb" 127.0.0.1:6379> SMEMBERS seta #查看seta的全部元素 1) "aaa" 2) "cc" 3) "222" 4) "bbb" 5) "111" 127.0.0.1:6379> SPOP seta 提取最後一個元素 "111" 127.0.0.1:6379> SMEMBERS seta 提取最後一個元素 ,那一個元素就消失在列表裏面 1) "aaa" 2) "cc" 3) "222" 4) "bbb" 127.0.0.1:6379> SPOP seta 提取最後一個元素 bbbb "bbb"
zadd zseta 11 123 //建立有序集合 127.0.0.1:6379> ZADD zseta 11 123 (integer) 1 127.0.0.1:6379> ZADD zseta 0 1ab (integer) 1 127.0.0.1:6379> ZRANGE zseta 1 -1 1) "1ab" 2) "123" 127.0.0.1:6379> ZRANGE zseta 0 -1 1) "-1" 2) "1ab" 3) "123" 刪除元素,上面添加了兩個元素,123,1ab 127.0.0.1:6379> ZREM zseta 1ab (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 #刪除成功了 1) "-1" 2) "123" 元素的索引值,以前先添加幾個值, 127.0.0.1:6379> ZADD zseta 10 1ab (integer) 1 127.0.0.1:6379> ZADD zseta 14 ssasb (integer) 1 127.0.0.1:6379> ZADD zseta 16 12123123 (integer) 1 127.0.0.1:6379> ZADD zseta 1000 sdasdf (integer) 1 127.0.0.1:6379> ZRANGE zseta 0 -1 1) "-1" 2) "1ab" 3) "123" 4) "ssasb" 5) "12123123" 6) "sdasdf" 127.0.0.1:6379> 返回元素的索引值,索引值從0開始,按score正向排序 127.0.0.1:6379> ZRANk zseta 1ab (integer) 1 127.0.0.1:6379> ZRANk zseta 123 (integer) 2 127.0.0.1:6379> ZRANk zseta ssasb (integer) 3 同上,不一樣的是,按score反序排序 127.0.0.1:6379> ZREVRANK zseta ssasb (integer) 2 反序顯示全部元素,並帶分值 127.0.0.1:6379> zrevrange zseta 0 -1
• hset user1 name aming //創建hash
• hset user1 age 30
• hset user1 job it
• hgetall user1
• hmset user2 name aming age 30 job it //批量創建鍵值對
• hmget user2
• hmget user2 name age job
• hdel user2 job //刪除指定filed
• hkeys user2 //打印全部的key
• hvals user2 //打印全部的values
• hlen user2 //查看hash有幾個filed
實例:
127.0.0.1 > hset user1 name aming //創建hash OK 127.0.0.1 > HGETALL hase2 127.0.0.1 > HMGET hash2 b c #獲取值 1) (nil) 2) (nil) 127.0.0.1 > hkeys user2 //打印全部的key 127.0.0.1 > hkeys user2 //打印全部的key 127.0.0.1 > hvals user2 //打印全部的values 127.0.0.1 > hlen user2 //查看hash有幾個filed
• keys * //取出全部key
• keys my* //模糊匹配
• exists name //有name鍵 返回1 ,不然返回0;
• del key1 // 刪除一個key //成功返回1 ,不然返回0;
• EXPIRE key1 100 //設置key1 100s後過時
• ttl key // 查看鍵 還有多長時間過時,單位是s,當 key 不存在時,返回 -2 。 當 key 存在但沒有設置剩餘生存時間時,返回 -1 。 不然,返回 key 的剩餘生存時間。
• select 0 //表明選擇當前數據庫,默認進入0 數據庫
• move age 1 // 把age 移動到1 數據庫
• persist key1 //取消key1的過時時間
• randomkey //隨機返回一個key
• rename oldname newname //重命名key
• type key1 //返回鍵的類型
注意:timeout指的是設置客戶端鏈接時的超時時間,單位爲秒。當客戶端在這段時間內沒有發出任何指令,那麼關閉該鏈接。
實例:
127.0.0.1::6877> keys * //取出全部key鍵 127.0.0.1::6877> keys my* //模糊匹配 127.0.0.1::6877> exists key1 //有name鍵 返回1 ,不然返回0; 1) "mykey" 127.0.0.1:6379> exists non 返回0; (integer) 0 127.0.0.1:6379> DEL key1 (integer) 1 127.0.0.1:6379> get key1 (nil) #空 127.0.0.1::6877> EXPIRE key1 10 //設置key1 10s後過時 (integer) 0 127.0.0.1:6379> get k1 "2" 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> EXPIRE key2 2 (integer) 1 127.0.0.1:6379> get key2 (nil) 127.0.0.1::6877> ttl key1 // 查看鍵 還有多長時間過時 127.0.0.1:6379> get key1 (integer)1 127.0.0.1:6379> ttl key2 (integer) -2 #已通過期兩秒 127.0.0.1:6379> SELECT 1 #進入1數據庫 OK 127.0.0.1::6877> keys * (empty list or set) 127.0.0.1:6379[1]> SELECT 0 # 進入0 數據庫 OK 127.0.0.1:6379> keys * #查看全部的鍵值 1) "k2" 2) "zseta" 3) "list2" 4) "setb" 5) "k3" 6) "mykey" 7) "k1" 8) "seta" 9) "set3" 10) "list1\xc2\xa0" 11) "set2" 12) "hash1" 13) "set1" 14) "user1" 127.0.0.1:6379> move set2 1 // 把set2 移動到1 數據庫 (integer) 1 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> keys * 1) "set2" 127.0.0.1::6877> EXPIRE mykey 10 #設置過時時間 (integer)1 127.0.0.1::6877> ttl mykey (integer) 8 127.0.0.1::6877> PERSIST mykey //取消key1的過時時間 (integer)1 127.0.0.1::6877> ttl mykey (integer) -1 127.0.0.1::6877> RANDOMKEY //每次執行,隨機返回一個key "set2" 127.0.0.1::6877> rename set2 set3 //重命名set3 OK 127.0.0.1::6877> keys set* #查看全部的鍵值 1) "set3" 127.0.0.1::6877> TYPE seta #查看數據類型 set 127.0.0.1:6379[1]> type seta none
• dbsize //返回當前數據庫中key的數目
• info //返回redis數據庫狀態信息
• flushdb //清空當前數據庫中全部的鍵
• flushall //清空全部數據庫中的全部的key
• bgsave //保存數據到 rdb文件中,在後臺運行
• save //做用同上,可是在前臺運行
• config get * //獲取全部配置參數
• config get dir //獲取配置參數
• config set dir //更改配置參數
• 數據恢復: 首先定義或者肯定dir目錄和dbfilename,而後把備份的rdb文件放到dir目錄下面,重啓redis服務便可恢復數據
實例:
127.0.0.1:6379[1]> DBSIZE //返回當前數據庫中key的數目 (integer) 1 127.0.0.1::6877>KEYS * 1) "set3 127.0.0.1::6877> info //返回redis數據庫狀態信息 127.0.0.1:6379> SELECT 1 OK 127.0.0.1:6376> KEYS * 1) "set3" 127.0.0.1::6877> flushdb //清空當前數據庫中全部的鍵 OK 127.0.0.1:6379[1]> KEYS * (empty list or set) 127.0.0.1::6877> flushall //清空全部數據庫中的全部的key 127.0.0.1::6877> bgsave //保存數據到 rdb文件中,在後臺運行 Background saving started 127.0.0.1::6877> save //做用同上,可是在前臺運行, 127.0.0.1::6877> config get * //獲取全部配置參數 127.0.0.1::6877> config get dir //獲取DIR配置參數 127.0.0.1::6877> config set dir //更改配置參數 127.0.0.1:6379[1]> CONFIG set timeout 5 #設置過時時間 OK 127.0.0.1:6379[1]> CONFIG get timeout #獲取過時時間 1) "timeout" 2) "5 查看數據恢復目錄 127.0.0.1:6379[1]> CONFIG get dir 1) "dir" 2) "/data/redis" 127.0.0.1:6379[1]> CONFIG get dbfilename 1) "dbfilename" 2) "dump.rdb"
數據恢復:把dump.rdb放到dir目錄,而後啓動,
• 設置監聽ip
• bind 127.0.0.1 2.2.2.2//能夠是多個ip,用空格分隔
• 設置監聽端口 ---修改默認端口,防止入侵
• port 16000
• 設置密碼,監聽內網ip或者以普通用戶的身份啓動
• requirepass aming>com #密碼aming>com
• redis-cli -a 'aming>com'
修改配置文件
• 將config命令更名
• rename-command CONFIG aming
• 禁掉config命令
• rename-command CONFIG 「」
不讓你的resdis.conf給別人看怎麼辦?好比經過限定文件或者目錄權限。
實例:
[root@localhost ~]# ls -l /data/redis/ 總用量 8 -rw-r--r-- 1 root root 2798 7月 9 10:38 appendonly.aof -rw-r--r-- 1 root root 534 7月 9 10:39 dump.rdb 查看redis啓動的用戶,保證安全,切換到普通用戶, 設置密碼 [root@localhost ~]# vim /etc/redis.conf /auth #搜索的內容 requirepass aming>com 啓動redis [root@localhost ~]# systemctl restart redis Failed to restart redis.service: Unit not found. [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #再次重啓服務 登陸redis,,,若是不使用密碼,登陸,執行keys *會報錯 [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> keys * #登陸成功 1) "zseta" 2) "k1" 3) "setb" 4) "k3" 5) "mykey" 6) "set1" 7) "list2" 8) "seta" 9) "set3" 10) "hash1" 11) "list1\xc2\xa0" 12) "user1" 13) "k2" 127.0.0.1:6379> • 將config命令更名 • rename-command CONFIG aming [root@localhost ~]# vim /etc/redis.conf #修改配置文件 /rename #搜索關鍵字,而後再下面添加 rename-command CONFIG aming [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #從新登陸 使用密碼登陸 [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> keys * 1) "k1" 2) "k3" 3) "k2" 4) "seta" 5) "list1\xc2\xa0" 6) "set3" 7) "user1" 8) "zseta" 9) "hash1" 10) "list2" 11) "setb" 12) "mykey" 13) "set1" 127.0.0.1:6379> config get dir #直接執行命令,不行 (error) ERR unknown command 'config' 127.0.0.1:6379> aming get dir #使用用戶名,能夠執行命令 1) "dir" 2) "/data/redis" 禁掉config命令,把裏面的aming用戶去掉就好了 • rename-command CONFIG 「」 [root@localhost ~]# vim /etc/redis.conf #修改配置文件 /rename #搜索關鍵字,而後再下面添加 rename-command CONFIG "" [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf #從新登陸
• 編輯配置文件/etc/redis.conf
• 針對慢查詢日誌,能夠設置兩個參數,一個是執行時長,單位是微秒,另外一個是慢查詢日誌的長度。當一個新的命令被寫入日誌時,最老的一條會從命令日誌隊列中被移除。若是超過1千,好比1001,那麼第一條就被移除了
• slowlog-log-slower-than 1000 / /單位ms,表示慢於1000ms則記錄日誌,
• slowlog-max-len 128 //定義日誌長度,表示最多存128條
• slowlog get //列出全部的慢查詢日誌
• slowlog get 2 //只列出2條
• slowlog len //查看慢查詢日誌條數
•
實例:
[root@localhost 01]# vim /etc/redis.conf slowlog-log-slower-than 10 表明超過10微秒,就記錄 slowlog-max-len 128 表明128條 啓動redis [root@localhost ~]# killall redis-server [root@localhost ~]# redis-server /etc/redis.conf [root@localhost ~]# redis-cli -a 'aming>com' 127.0.0.1:6379> SLOWLOG get 查看記錄 1) 1) (integer) 0 #由於運行一個命令,記錄從0開始,0表示1條,因此顯示0 2) (integer) 1531106988 3) (integer) 390 4) 1) "COMMAND" 5) "127.0.0.1:50952" 6) "" 127.0.0.1:6379> get k3 "a" 127.0.0.1:6379> get k2 "2" 127.0.0.1:6379> SLOWLOG get #又執行兩條命令,以後顯示三條記錄 1) 1) (integer) 1 2) (integer) 1531106998 3) (integer) 18 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:50952" 6) "" 2) 1) (integer) 0 2) (integer) 1531106988 3) (integer) 390 4) 1) "COMMAND" 5) "127.0.0.1:50952" 6) 127.0.0.1:6379> SLOWLOG get 1 #只顯示最新的一條記錄,get後面的數字,表明顯示的條數 1) 1) (integer) 2 2) (integer) 1531107114 3) (integer) 21 4) 1) "SLOWLOG" 2) "get" 5) "127.0.0.1:50952" 6) "" 127.0.0.1:6379> slowlog len //查看慢查詢日誌條數 integer) 4
php鏈接redis以前要安裝redis擴展模塊
• cd /usr/local/src
• wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip
• unzip phpredis.zip
• cd phpredis-develop
• /usr/local/php-fpm/bin/phpize
注意:有的人目錄是/usr/local/php/bin/phpize,編譯的時候把php-fpm換成php
• ./configure --with-php-config=/usr/local/php-fpm/bin/php-config
• make
• make install
• vim /usr/local/php.ini //增長extension=redis.so
• /usr/local/php-fpm/bin/php -m|grep redis //看是否有redis模塊
• 重啓php-fpm服務
實例:
[root@localhost 01]# cd /usr/local/src [root@localhost src]# wget https://coding.net/u/aminglinux/p/yuanke_centos7/git/raw/master/21NOSQL/phpredis.zip [root@localhost src]# unzip phpredis.zip [root@localhost src]# cd phpredis-develop [root@localhost phpredis-develop]# /usr/local/php/bin/phpize Configuring for: PHP Api Version: 20131106 Zend Module Api No: 20131226 Zend Extension Api No: 220131226 [root@localhost phpredis-develop]# ./configure --with-php-config=/usr/local/php-fpm/bin/php-config checking for grep that handles long lines and -e... /usr/bin/grep checking for egrep... /usr/bin/grep -E checking for a sed that does not truncate output... /usr/bin/sed checking for cc... cc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether cc accepts -g... yes checking for cc option to accept ISO C89... none needed checking how to run the C preprocessor... cc -E checking for icc... no checking for suncc... no checking whether cc understands -c and -o together... yes checking for system library directory... lib checking if compiler supports -R... no checking if compiler supports -Wl,-rpath,... yes checking build system type... x86_64-unknown-linux-gnu checking host system type... x86_64-unknown-linux-gnu checking target system type... x86_64-unknown-linux-gnu configure: error: Cannot find php-config. Please use --with-php-config=PATH [root@localhost phpredis-develop]# make [root@localhost phpredis-develop]# make install Installing shared extensions: /usr/local/php/lib/php/extensions/no-debug-non-zts-20131226/ [root@localhost 01]# vim /usr/local/php.ini//增長extension=redis.so #查看地下有沒有redis [root@localhost phpredis-develop]# /etc/init.d/php-fpm restart #啓動PHP服務 Gracefully shutting down php-fpm . done Starting php-fpm done
• vim /usr/local/php-fpm/etc/php.ini//更改或增長
session.save_handler = "redis"
session.save_path = "tcp://127.0.0.1:6379"
• 或者apache虛擬主機配置文件中也能夠這樣配置:
php_value session.save_handler " redis"
php_value session.save_path " tcp://127.0.0.1:6379"
• 或者php-fpm配置文件對應的pool中增長:
php_value[session.save_handler] = redis
php_value[session.save_path] = " tcp://127.0.0.1:6379 "
• wget http://study.lishiming.net/.mem_se.txt
• mv .mem_se.txt /usr/local/apache2/htdocs/session.php
• 其中session.php內容能夠參考https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/21NOSQL/session.php
• curl localhost/session.php //結果相似於1443702394<br><br>1443702394<br><br>i44nunao0g3o7vf2su0hnc5440
• 命令行鏈接redis,也能夠查看到該key以及對應的值
• 若是想用php鏈接redis cluster,須要使用predis擴展
• 安裝方法相似phpredis,predis擴展地址https://github.com/nrk/predis
實例:
[root@localhost 01]# vim /usr/local/php-fpm/etc/php.ini [aming.com] listen = /tmpaming.sock lsiten.mode = 666 user = php-fpm grou = php-fpm pm = dynamic pm.max_children = 50 pm.start_servers = 20 pm.min_spare_servers = 5 pm.maxpare_servers = 35 pm.max_requests = 500 rlimit_files =1024 session.save_handler = "redis" //更改或增長 session.save_path = "tcp://127.0.0.1:6379" [root@localhost phpredis-develop]# /etc/init.d/php-fpm restart #重啓服務 Gracefully shutting down php-fpm . done Starting php-fpm done [root@localhost phpredis-develop]# vim /etc/redis.conf requirepass #搜索的內容 requirepass aming>com 前面添加# 重啓服務 [root@localhost phpredis-develop]# killall redis-server [root@localhost phpredis-develop]# redis-server /etc/redis.conf 測試 [root@localhost phpredis-develop]# cd /data/wwwroot/default/ [root@localhost default]# ls #下面 有m.php 文件 index.html vhost m.php info.php [root@localhost phpredis-develop# cat m.php [root@localhost phpredis-develop]# cat 1.php #1.php是關於session [root@localhost default]# curl localhost/1.php #多執行幾回 [root@localhost 01]# redis cli #查看執行的記錄 [root@localhost 01]# [root@localhost 01]#
• 爲了節省資源,咱們能夠在一臺機器上啓動兩個redis服務
• cp /etc/redis.conf /etc/redis2.conf
• vim /etc/redis2.conf //須要修改port,dir,pidfile,logfile
• 還要增長一行
• slaveof 127.0.0.1 6379
• 若是主上設置了密碼,還須要增長
• masterauth aminglinux>com //設置主的密碼
• 啓動以前不要忘記建立新的dir目錄
• redis-server /etc/redis2.conf
• 測試:在主上建立新的key,在從上查看
• 注意:redis主從和mysql主從不同,redis主從不用事先同步數據,它會自動同步過去
實例:
搭建主從
[root@localhost 01]# cp /etc/redis.conf /etc/redis2.conf [root@localhost 01]# vim /etc/redis2.conf //須要修改port,dir,pidfile,logfile port 6380 #端口修改爲6380 pidfile /var/run/redis_6380.pid logfile '/var/log/redis.log' 修改爲'/var/log/redis2.log' dir /data/redis 改爲 dir /data/redis2 slaveof 127.0.0.1 6379 增長一行 啓動 [root@localhost 01]# mkdir /data/redis2/ [root@localhost 01]# redis-server /etc/redis2.conf [root@localhost 01]# ps aux | grep redis #查看進程 [root@localhost 01]# netstat -lntp # 查看redis-server的端口 [root@localhost 01]# redis-cli -h 127.0.0.1 -p 6380 127.0.0.1:6379> keys * 1) "k2" 2) "zseta" 3) "list2" 4) "setb" 5) "k3" 6) "mykey" 7) "k1" 8) "seta" 9) "set3" 10) "list1\xc2\xa0" 11) "hash1" 12) "set1" 13) "user1" 127.0.0.1:6380 > aming get dir 127.0.0.1:6380 > aming get dbfilename 127.0.0.1:6380 > aming get * #查看全部的元素 [root@localhost 01]# vim /etc/redis.conf slave-read-only yes #設置只讀模式 [root@localhost 01]#redis-cli -h 127.0.0.1 -p 6380 127.0.0.1:6379> keys * (error)READONLY You can't write against a read only slave.
常見問題:
一、爲啥,啓動的時候,只用redis-server /etc/redis.conf 命令就能啓動,而不是src/redis-server /etc/redis.conf 呢
答:由於你的redis-server命令已經放到了PATH裏面了。 你which redis-server能顯示路徑出來,說明已經放到PATH裏了。
二、,Redis啓動時提示 Redis配置文件194行always-show-logo yes
答:找到緣由了。。。由於以前安裝過Redis,衝突了
三、配置了redis的RDB模式的持久化,也在redis 更新了數據 爲何不會自動生成一個備份的文件呢?
答:要重啓服務才生效。
四、127.0.0.1:6379> SET key "123 100"
OK
這樣就能夠啦。
答:這樣寫的話, value的值是123 100, 而不是設置過時時間爲100了吧
五、每次重啓redis,都會生成一個新的dump.rdb 文件,我備份的rdb文件是123.rdb,把備份的123.rdb 拷到dir目錄下,同時重命名爲dump.rdb, 查詢k 依然爲空,,怎麼備份恢復
答:把123.rdb 更名爲dump.rdb, 再重啓。
恢復優先使用aof,因而關閉aof以後就能成功經過dump.rdb 恢復備份了
六、使用bgsave 把數據存儲到rdb文件後,備份了rdb文件,使用flushall 清空全部數據庫k,殺掉redis進程,把rdb備份文件從新拷回redis數據目錄中後,重啓redis,使用 keys * 查詢k,顯示爲空,這是爲何??
答:在清數據以前,就要將dump.rdb 文件備份好,查看使用的dbfile是否是這個rdb文件
七、