1. 程式人生 > >2018-08-22(redis)

2018-08-22(redis)

tomat 實施 raw 直接 data 第一個元素 lin save conf

21.9 redis介紹

一、介紹
redis 是一個開源的、使用C語言編寫的、支持網絡交互的、可以基於內存也可以持久化的Key-Value數據庫。
redis的源碼非常簡單,只要有時間看看譚浩強的C語言,在去看redis的源碼能看懂50-60%。
redis目前最大的集群應該是新浪的應該。
redis目前是vmvaer來支持的,很多的開源軟件都需要某些組織來支持的。如果一個開源軟件沒有金錢來支持的話很難走的持久

二、Redis和Memcache對比
技術分享圖片

持久化:以電商舉例,session用memcache來做的,購物車用redis來做的,當你退出的時候會提示你購物車裏的物品會在你退出後繼續保存。相對來說memcache存儲更單一化!

主從復制:redis的主從復制類似mysql的主從復制但是原理是不同的!
虛擬內存:說白了就是把內存裏一些不用的東西放在硬盤上,最好不要用,降低效率,現在內存來說比較便宜。

21.10 redis安裝

cd /usr/local/src/
wget http://download.redis.io/releases/redis-4.0.1.tar.gz
tar zxvf redis-4.0.1.tar.gz
cd redis-4.0.1
make && make install
cp redis.conf /etc/redis.conf

如果安裝時報錯:

zmalloc.h:50:31: 致命錯誤:jemalloc/jemalloc.h:沒有那個文件或目錄

解決方案:

執行命令:make MALLOC=libc&&make install

vim /etc/redis.conf #修改如下配置
#把

daemonize no
#改成
daemonize yes
#no前臺啟動,yes後臺啟動
logfile "/var/log/redis.log"     #定義日誌文件
dir /data/redis/             #redis文件存放路徑
appendonly yes                   #開啟aof,aof名字:apendonly.aof

創建上面指定的dir

mkdir /data/redis`

兩項內核參數,沒必要修改時保持默認

在rc.local添加此兩項參數,開啟時可以啟動

sysctl vm.overcommit_memory=1
echo never > /sys/kernel/mm/transparent_hugepage/enabled

啟動Redis服務

redis-server /etc/redis.conf`

檢查進程

ps aux |grep redis
root       2233  0.0  0.2 141952  2212 ?        Ssl  10:00   0:30 redis-server 127.0.0.1:6379
root      11624  0.0  0.0 112720   968 pts/0    S+   20:44   0:00 grep --color=auto redis

21.11 redis持久化

數據存放在內存裏,無論是讀和寫都是非常快的,但是如果重啟服務器或者重啟服務,數據都會因此丟失。所以,數據較為重要的話,需要實施數據持久化。
Redis提供了兩種持久化的方式,分別是RDB(Redis DataBase)和AOF(Append Only File)
RDB,簡而言之,就是在不同的時間點,將redis存儲的數據生成快照並存儲到磁盤等介質上。#簡單來說,就是把內存的數據做一個鏡像,然後完整映射存儲到磁盤上面。
存儲方式是通過redis.conf的save參數來定義存儲方式。
配置文件有以下字段

緩存設置:配置文件中save選項 
save 900 1 # 900秒內有至少1個鍵被更改則進行快照 
save 300 10 # 300秒內有至少10個鍵被更改則進行快照 
save 60 10000 # 60秒內有至少10000個鍵被更改則進行快照

滿足這3個條件則會觸發持久化存儲
如果把持久化關閉,則把save參數條件都deleted,然後把#save "" 註釋去掉,改成這樣
save ""
AOF,則是換了一個角度來實現持久化,那就是將redis執行過的所有寫指令記錄下來,在下次redis重新啟動時,只要把這些寫指令從前到後再重復執行一遍,就可以實現數據恢復了。#數據隨著操作時間的增長而增長。
其實RDB和AOF兩種方式也可以同時使用,在這種情況下,如果redis重啟的話,則會優先采用AOF方式來進行數據恢復,這是因為AOF方式的數據恢復完整度更高。
AOF有三種方式,也是在配置文件redis.conf中定義的

appendfsync always#一直寫,每次變更就寫
appendfsync everysec            #每秒寫
appendfsync no#每隔一段時間寫,最不安全的

如果你沒有數據持久化的需求,也完全可以關閉RDB和AOF方式,這樣的話,redis將變成一個純內存數據庫,就像memcache一樣。
兩者對比,AOF保存比較存儲比較安全

21.12 redis數據類型

Redis數據類型-string

string為最簡單的類型,與Memcached一樣的類型,一個key對應一個value,其支持的操作與Memcached的操作類似,它的功能更豐富。設置可以存二進制的對象。

示例:

# redis-cli #連接redis的命令,redis通用入口命令
set設置單個key-value
get單個值

127.0.0.1:6379> set key1 10
OK
127.0.0.1:6379> get key1
"10"
#mset設置多個key-value
#mget多個值
127.0.0.1:6379> mset key2 20 key3 30
OK
127.0.0.1:6379> mget key1 key2 key3
1) "10"
2) "20"
3) "30"

Redis數據類型-list

list是一個鏈表結構,主要功能是push、pop、獲取一個範圍的所有值等等。操作中key理解為鏈表的名字。

使用 list 結構,我們可以輕松地實現最新消息排行等功能(比如新浪微博的 TimeLine )。

list 的另一個應用就是消息隊列,可以利用 list 的 push操作,將任務存在 list 中,然後工作線程再用pop操作將任務取出進行執行。

push與pop的是推擠特性,push將k-v推進list,然後pop把值排出來

 127.0.0.1:6379> LPUSH list1 111
(integer) 1
127.0.0.1:6379> LPUSH list1 222
(integer) 2
127.0.0.1:6379> LPUSH list1 333
(integer) 3
#LRANGE查值,0 -1表示倒序
127.0.0.1:6379> LRANGE list1 0 -1
1) "333"
2) "222"
3) "111"
#LPOP取值,取值後,list會缺少被取出的值
127.0.0.1:6379> LPOP list1
"333"
127.0.0.1:6379> LRANGE list1 0 -1
1) "222"
2) "111"

Redis數據類型-set
set是集合,和我們數學中的集合概念相似,對集合的操作有添加刪除元素,有對多個集合求交並差等操作。操作中key理解為集合的名字。比如在微博應用中,可以將一個用戶所有的關註人存在一個集合中,將其所有粉絲存在一個集合。因為 Redis 非常人性化的為集合提供了求交集、並集、差集等操作,那麽就可以非常方便的實現如共同關註、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中。
set示例

 #SADD
127.0.0.1:6379> SADD set1 1
(integer) 1
127.0.0.1:6379> SADD set1 2
(integer) 1
127.0.0.1:6379> SADD set1 3
(integer) 1
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 set2 2
(integer) 1
127.0.0.1:6379> SADD set2 3
(integer) 1
127.0.0.1:6379> SADD set2 4
(integer) 1
127.0.0.1:6379> SADD set2 a
(integer) 1
127.0.0.1:6379> SADD set2 b
(integer) 1
#SMEMBERS 查key值
127.0.0.1:6379> SMEMBERS set1
1) "1"
2) "a"
3) "3"
4) "2"
5) "b"
#SMEMBERS 查key值
127.0.0.1:6379> SMEMBERS set2
1) "a"
2) "4"
3) "3"
4) "2"
5) "b"
#SINTER 求交集
127.0.0.1:6379> SINTER set1 set2
1) "a"
2) "3"
3) "2"
4) "b"
#SUNION 去重,並集
127.0.0.1:6379> SUNION set1 set2
1) "1"
2) "a"
3) "2"
4) "b"
5) "4"
6) "3"
#SDIFF 求差集
127.0.0.1:6379> SDIFF set1 set2
1) "1"
#SREM 刪除元素
127.0.0.1:6379> SREM set1 1
(integer) 1
127.0.0.1:6379> SMEMBERS set1
1) "a"
2) "3"
3) "2"
4) "b"

解釋:

127.0.0.1:6379> SINTER set1 set2 //交集,相同的交集一起

127.0.0.1:6379> SUNION set1 set2 //並集,set1,set2去重合並

127.0.0.1:6379> SDIFF set1 set2 //差集,不同的元素

127.0.0.1:6379> SREM set1 c //刪除元素

127.0.0.1:6379> SADD set2 a 2  b

Redis數據類型-sort set

sorted set是有序集合,它比set多了一個權重參數score,使得集合中的元素能夠按 score 進行有序排列,比如一個存儲全班同學成績的 Sorted Sets,其集合 value 可以是同學的學號,而 score 就可以是其考試得分,這樣在數據插入集合的時候,就已經進行了天然的排序。

127.0.0.1:6379> ZADD set3 10 a
(integer) 1
127.0.0.1:6379> ZADD set3 20 "a-2"
(integer) 1
127.0.0.1:6379> ZADD set3 30 b
(integer) 1
127.0.0.1:6379> ZADD set3 40 b-2
(integer) 1
#順序
127.0.0.1:6379> ZRANGE set3 0 -1
1) "a"
2) "a-2"
3) "b"
4) "b-2"
#倒序
127.0.0.1:6379> ZREVRANGE set3 0 -1
1) "b-2"
2) "b"
3) "a-2"
4) "a"

##排序的時候,score值不會被顯示出來的
Redis數據類型-hash
在 Memcached 中,我們經常將一些結構化的信息打包成 hashmap,在客戶端序列化後存儲為一個字符串的值(一般是 JSON 格式),比如用戶的昵稱、年齡、性別、積分等。
示例
格式:
#HSET key value(多個元素)

127.0.0.1:6379> HSET hash1 name luo
(integer) 1
127.0.0.1:6379> HSET hash1 age 28
(integer) 1
127.0.0.1:6379> HSET hash1 job IT
(integer) 1
#HGET key value
127.0.0.1:6379> HGET hash1 name
"luo"
127.0.0.1:6379> HGET hash1 job
"IT"
127.0.0.1:6379> HGET hash1 age
"28"
#HGETALL 獲取全部hash value
127.0.0.1:6379> HGETALL hash1
1) "name"
2) "luo"
3) "age"
4) "28"
5) "job"
6) "IT"

21.13/21.14/21.15 redis常用操作

Redis常用操作 (string, list)

set key1 aminglinux
 get key1
 set key1 aming//第二次賦值會覆蓋
 setnx key2 aaa //返回1 如果key2不存在直接創建key
 setnx key2 bbb  //返回0,如果key2存在,返回0
 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 //從右側取出第一個元素

string

 #set,get用法
 set key1 aminglinux
 get key1
 #set第二次被覆蓋
 set key1 aming//第二次賦值會覆蓋
 #setnx 檢查key值是否存在,key存在,則不被覆蓋,key不存在,直接創建key
 127.0.0.1:6379> get key1
"10"
127.0.0.1:6379> get key10
(nil)
 127.0.0.1:6379> SETNX key1 100
(integer) 0
127.0.0.1:6379> SETNX key10 100
(integer) 1
#設置過期時間,
格式:set `key` `value` ex `time`
127.0.0.1:6379> set key11 111 ex 10
OK
#setex用法,給key11設置過期時間為10s,值為1,若key已經存在,會覆蓋新的值
格式: SETEX `key` `seconds` `value`
127.0.0.1:6379> SETEX key11 1000 11
OK
127.0.0.1:6379> get key11
"11"
list
127.0.0.1:6379> LPUSH list11 aaa
(integer) 1
127.0.0.1:6379> LPUSH list11 bbb
(integer) 2
127.0.0.1:6379> LPUSH list11 ccc
(integer) 3
127.0.0.1:6379> LRANGE list11 0 -1
1) "ccc"
2) "bbb"
3) "aaa"
#從左側取出第一個元素 ,最上的一個元素
127.0.0.1:6379> LPOP list11
"ccc"
#從右側取出第一個元素,最下的一個元素
127.0.0.1:6379> RPOP list11
"aaa"
#取出的value,不會再存在list裏面
127.0.0.1:6379> LRANGE list11 0 -1
1) "bbb"

Redis常用操作(list, set)

 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
#在xxx的前面插入一個元素為xxx
127.0.0.1:6379> LRANGE list11 0 -1
1) "bbb"
127.0.0.1:6379> LINSERT list11 before bbb aaa
(integer) 2
127.0.0.1:6379> LRANGE list11 0 -1
1) "aaa"
2) "bbb"
#在xxx的後面插入一個元素為xxx
127.0.0.1:6379> LINSERT list11 after bbb ccc
(integer) 3
127.0.0.1:6379> LRANGE list11 0 -1
1) "aaa"
2) "bbb"
3) "ccc"
#把第1個元素修改為123 ,用下標表示,0=no.1,1=no.2,以此類推
格式 LET `key` `位置` `value`
127.0.0.1:6379> LSET list11 0 123
OK
127.0.0.1:6379> LRANGE list11 0 -1
1) "123"
2) "bbb"
3) "ccc"
#查看第一個元素
127.0.0.1:6379> LRANGE list11 0 -1
1) "123"
2) "bbb"
3) "ccc"
127.0.0.1:6379> LINDEX list11 0
"123"
#查看鏈表中有幾個元素
LLEN list11
#隨機取出一個元素,刪除
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> SPOP seta
"aaa"
127.0.0.1:6379> SMEMBERS seta
1) "bbb"

Redis常用操作(set, zset)

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> ZADD zseta 11 123
(integer) 1
127.0.0.1:6379> ZADD zseta 22 223
(integer) 1
127.0.0.1:6379> ZRANGE zseta 0 -1
1) "123"
2) "223"
#刪除指定元素
127.0.0.1:6379> ZREM zseta 123
(integer) 1
127.0.0.1:6379> ZREM zseta 223
(integer) 1
#返回元素的索引值,索引值(integer後面的值)從0開始,按score正向排序,
127.0.0.1:6379> ZADD zseta 10 aaa
(integer) 1
127.0.0.1:6379> ZADD zseta 30 cccc
(integer) 1
127.0.0.1:6379> ZADD zseta 20 bbb
(integer) 1
127.0.0.1:6379> ZRANGE zseta 0 -1
1) "aaa"
2) "bbb"
3) "cccc"
127.0.0.1:6379> ZRANk zseta aaa
(integer) 0
127.0.0.1:6379> ZRANk zseta ccc
(nil)
127.0.0.1:6379> ZRANk zseta cccc
(integer) 2
#反序排序
127.0.0.1:6379> ZREVRANGE zseta 0 -1
1) "cccc"
2) "bbb"
3) "aaa"

Redis常用操作(hash)

 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

21.16 redis操作鍵值

查看redis的鍵值,支持模糊匹配,例如:#key k*

127.0.0.1:6379> keys *
1) "h1"
2) "key"
3) "list1"
4) "key2"
5) "key3"
6) "zseta"
7) "11"
8) "set1"
9) "key1"
10) "set2"
11) "set3"

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 數據庫
示例:

127.0.0.1:6379> SMEMBERS set2
1) "3"
2) "2"
3) "4"
4) "c"
5) "b"
6) "5"
127.0.0.1:6379> MOVE set2 1
(integer) 1
127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> keys *
1) "set2"

persist key1 //取消key1的過期時間
示例:

127.0.0.1:6379> EXPIRE 11 1000
(integer) 1
127.0.0.1:6379> TTL 11
(integer) 996
127.0.0.1:6379> PERSIST 11
(integer) 1
127.0.0.1:6379> TTL 11
(integer) -1
#key值存在,但是沒有過期時間

randomkey //隨機返回一個key

127.0.0.1:6379> RANDOMKEY
"key3"
127.0.0.1:6379> RANDOMKEY
"set1"
127.0.0.1:6379> RANDOMKEY
"set3"
127.0.0.1:6379> RANDOMKEY
"set1"

rename oldname newname //重命名key

127.0.0.1:6379> RENAME 11 key11
OK
127.0.0.1:6379> keys key11
1) "key11"

type key1 //返回鍵的類型
示例:

127.0.0.1:6379> TYPE h1
hash
127.0.0.1:6379> TYPE key11
string
127.0.0.1:6379> TYPE set3
zset

Redis常用操作(服務)

dbsize //返回當前數據庫中key的數目

127.0.0.1:6379> keys *
1) "key11"
2) "h1"
3) "key"
4) "list1"
5) "key2"
6) "key3"
7) "zseta"
8) "set1"
9) "key1"
10) "set3"
127.0.0.1:6379> DBSIZE
(integer) 10

info //返回redis數據庫狀態信息
flushdb //清空當前數據庫中所有的鍵

127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> keys *
1) "set2"
127.0.0.1:6379[1]> FLUSHDB
OK
127.0.0.1:6379[1]> keys *
(empty list or set)

flushall //清空所有數據庫中的所有的key
bgsave //保存數據到 rdb文件中,在後臺運行
適用環境:內存寫入redis數據量龐大,需要遷移到後臺rdb文件操作。
響應速度:取決於數據量的多少。
save //作用同上,但是在前臺運行
操作環境:當前窗口

config get * //獲取所有配置參數

127.0.0.1:6379[1]> CONFIG GET *
.
.
.
164) ""
165) "notify-keyspace-events"
166) ""
167) "bind"
168) "127.0.0.1"

config get dir //獲取配置參數

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"
127.0.0.1:6379> CONFIG GET bind
1) "bind"
2) "127.0.0.1"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
config set dir  //更改配置參數
127.0.0.1:6379> CONFIG SET timeout 100
OK
127.0.0.1:6379> CONFIG GET timeout
1) "timeout"
2) "100"

數據恢復: 首先定義或者確定dir目錄和dbfilename,然後把備份的rdb文件放到dir目錄下面,重啟redis服務即可恢復數據

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"
127.0.0.1:6379> CONFIG GET dbfilename
1) "dbfilename"
2) "dump.rdb"
#dump.rdb的名字可以自定義更改

21.17 redis安全設置

iptables設置對6379端口的保護,以免涉外操控。

設置監聽ip,在配置文件redis.conf中定義

bind 127.0.0.1  2.2.2.2`
#可以是多個ip,用空格分隔

(如果不設置這個配置,默認監聽所有,公網ip,內網ip。。。)
設置監聽端口

port 16000

設置密碼

修改參數(如果無該參數,手動追加)

格式:requirepass 密碼

vim /etc/redis.conf
# even if no authentication is configured, nor a specific set of interfaces
# are explicitly listed using the "bind" directive.
protected-mode yes
requirepass luolinux>aaa  

#添加requirepass參數定義登錄密碼
修改參數後,重啟redis服務並連接redis數據庫

killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

登錄命令:

# redis-cli -a ‘luolinux>aaa‘`
127.0.0.1:6379> keys *
1) "key11"
2) "h1"
3) "key"
4) "list1"
5) "key2"
6) "key3"
7) "zseta"
8) "set1"
9) "key1"
10) "set3"

將config命令改名

config命令在redis的效果

127.0.0.1:6379> CONFIG GET dir
1) "dir"
2) "/data/redis"

這是修改前的效果,config能獲取很多數據,如果×××***會獲取核心數據內容。

修改參數(如果無該參數,手動追加): rename-command CONFIG aming

vim /etc/redis.conf
# security of read only slaves using ‘rename-command‘ to shadow all the
# administrative / dangerous commands.
slave-read-only yes
rename-command CONFIG aming
#添加參數,修改config的命令符為"aming",意思就是鍵入aming相當於鍵入config的效果
修改參數後,重啟redis服務並連接redis數據庫
killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

可以看到"aming"命令已經生效

127.0.0.1:6379> aming get dir
1) "dir"
2) "/data/redis"
而"config"命令已經失效
127.0.0.1:6379> CONFIG GET dir
(error) ERR unknown command ‘CONFIG‘

禁掉config命令

#把“”引用部分的內容改空即可

rename-command CONFIG “”`

21.18 redis慢查詢日誌

開啟慢查詢日誌功能

編輯配置文件/etc/redis.conf

vim /etc/redis.conf
slowlog-log-slower-than 10000
slowlog-max-len 128

解釋:

針對慢查詢日誌,可以設置兩個參數,一個是執行時長,單位是微秒,另一個是慢查詢日誌的長度。當一個新的命令被寫入日誌時,最老的一條會從命令日誌隊列中被移除。

slowlog-log-slower-than 1000
#單位ms,表示慢於1000ms則記錄日誌
slowlog-max-len 128
#定義日誌長度,表示最多存128條

修改慢查詢的參數為10ms進行測試(其實正常執行的命令都>10ms)

slowlog-log-slower-than 10000
改成
slowlog-log-slower-than 10

修改後重啟redis

killall redis-server
redis-server /etc/redis.conf
redis-cli -a "luolinux>aaa"

鍵入任意執行命令進行測試

127.0.0.1:6379> SLOWLOG get
1)  1) (integer) 0
   2) (integer) 1534932088
   3) (integer) 1035
   4) 1) "COMMAND"
   5) "127.0.0.1:44242"
   6) ""
127.0.0.1:6379> keys *
1) "key2"
2) "key11"
3) "key1"
4) "h1"
5) "set1"
6) "zseta"
7) "list1"
8) "key3"
9) "set3"
10) "key"
127.0.0.1:6379> keys set3
1) "set3"

slowlog get //列出所有的慢查詢日誌

127.0.0.1:6379> SLOWLOG get
1)   1) (integer) 3
   2) (integer) 1534932157
   3) (integer) 23
   4) 1) "keys"
      2) "set3"
   5) "127.0.0.1:44242"
   6) ""
2)   1) (integer) 2
   2) (integer) 1534932144
   3) (integer) 61
   4) 1) "keys"
      2) "*"
   5) "127.0.0.1:44242"
   6) ""
3)   1) (integer) 1
   2) (integer) 1534932130
   3) (integer) 18
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""
4)   1) (integer) 0
   2) (integer) 1534932088
   3) (integer) 1035
   4) 1) "COMMAND"
   5) "127.0.0.1:44242"
   6) ""

slowlog get 1 //列出最近的1條慢查詢

127.0.0.1:6379> SLOWLOG get 1
1)   1) (integer) 4
   2) (integer) 1534932175
   3) (integer) 389
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""

slowlog get 2 //只列出最近的2條

 127.0.0.1:6379> SLOWLOG get 2
1)  1) (integer) 5
   2) (integer) 1534932261
   3) (integer) 43
   4)   1) "SLOWLOG"
      2) "get"
      3) "1"
   5) "127.0.0.1:44242"
   6) ""
2)  1) (integer) 4
   2) (integer) 1534932175
   3) (integer) 389
   4) 1) "SLOWLOG"
      2) "get"
   5) "127.0.0.1:44242"
   6) ""

slowlog len //查看慢查詢日誌條數

127.0.0.1:6379> SLOWLOG len
(integer) 7

21.19 php安裝redis擴展

PHP中使用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
./configure --with-php-config=/usr/local/php-fpm/bin/php-config
make 
make install
vim /usr/local/php.ini 
##增加extension=redis.so
##看是否有redis模塊
/usr/local/php-fpm/bin/php -m|grep redis
redis
##重啟php-fpm服務

21.20 redis存儲session

PHP中使用redis – 存儲session

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中增加:

vim /usr/local/php-fpm/etc/php-fpm.d/www.conf
php_value[session.save_handler] = redis
php_value[session.save_path] = " tcp://127.0.0.1:6379 "

#順便也可以把redis.conf的密碼給刪掉或者註釋掉

vim /etc/redis.conf
#requirepass luolinux>aaa

下載測試文件

進入localhost的目錄

cd /data/web/www.com/
wget http://study.lishiming.net/.mem_se.txt
mv .mem_se.txt  test.php

其中test.php內容可以參考https://coding.net/u/aminglinux/p/yuanke_centos7/git/blob/master/21NOSQL/session.php
或者手動添加php測試參數

vim test.php  
<?php
session_start();
if (!isset($_SESSION[‘TEST‘])) {
$_SESSION[‘TEST‘] = time();
}
$_SESSION[‘TEST3‘] = time();
print $_SESSION[‘TEST‘];
print "<br><br>";
print $_SESSION[‘TEST3‘];
print "<br><br>";
print session_id();
?>

多次curl 取key-value數據

[root@localhost ~]# curl localhost/11.php
1535016218<br><br>1535016218<br><br>mh2404u6koq5s7q8lvmothf385
[root@localhost ~]# curl localhost/11.php
1535016219<br><br>1535016219<br><br>nsvpsvca8kgg0ars2gpjavm5g2
[root@localhost ~]# curl localhost/11.php
1535016219<br><br>1535016219<br><br>gvus9tekjoaac0i2d9lu0g12d1
[root@localhost ~]# curl localhost/11.php
1535016220<br><br>1535016220<br><br>mp9rmfj0f0simu450hp1gkh090
[root@localhost ~]# curl localhost/11.php
1535016220<br><br>1535016220<br><br>jorriqau86qu9t9appjg94m4f2

進入數據庫

查key值

[root@localhost ~]# redis-cli
127.0.0.1:6379> keys *
1) "key1"
2) "PHPREDIS_SESSION:jorriqau86qu9t9appjg94m4f2"
3) "key2"
4) "PHPREDIS_SESSION:mh2404u6koq5s7q8lvmothf385"
5) "list1"
6) "PHPREDIS_SESSION:nsvpsvca8kgg0ars2gpjavm5g2"
7) "PHPREDIS_SESSION:mp9rmfj0f0simu450hp1gkh090"
8) "set3"
9) "list11"
10) "set1"
11) "zseta"
12) "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
13) "hash1"
14) "seta"
15) "key10"
16) "key3"
17) "set2"
18) "PHPREDIS_SESSION:gvus9tekjoaac0i2d9lu0g12d1"

查看key的value

127.0.0.1:6379> get "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
"TEST|i:1535016167;TEST3|i:1535016167;"
解釋:
get "PHPREDIS_SESSION:sm284t8p6bsdraovvkildjt1a0"
#這個是key
"TEST|i:1535016167;TEST3|i:1535016167;"
#這個是value
 針對redis集群

如果想用php連接redis cluster,需要使用predis擴展
安裝方法類似phpredis,predis擴展地址https://github.com/nrk/predis

21.21 redis主從配置

Redis主從復制原理
通過把這個RDB文件或AOF文件傳給slave服務器,slave服務器重新加載RDB文件,來實現復制的功能!

復制的話:主服務器可以有多個從服務器!!! 不僅這樣從服務器還可以有從服務器,可以做成星狀的結構!
復制的話也不會阻塞進程,同樣fork一個子進程來做!

復制的原理:
當建立一個從服務器後,從服務器會想主服務器發送一個SYNC的命令,主服務器接收到SYNC命令之後會執行BGSAVE
然後保存到RDB文件,然後發送到從服務器!收到RDB文件然後就載入到內存!

配置非常簡單:
要把:192.168.66.131 6380 作為192.168.66.131 6379的從就一條命令

192.168.66.131:6380> slaveof 192.168.66.131 6379
OK
然後使用INFO查看下:
192.168.66.131:6380>INFO
# Replication
role:slave
master_host:192.168.66.131
master_port:6379
master_link_status:up
master_last_io_seconds_ago:7
master_sync_in_progress:0
slave_repl_offset:85
slave_priority:100
slave_read_only:1
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

然後在到主的上面看下:

[root@localhost ~]# redis-cli -h 192.168.66.131 -p 6379
192.168.66.131:6379> INFO
# Replication
role:master
connected_slaves:1
slave0:ip=192.168.66.131,port=6380,state=online,offset=183,lag=1    #
master_repl_offset:183
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:182

從2.61 的時候!從是僅讀的

192.168.66.131:6380> SET key1 2
(error) READONLY You can‘t write against a read only slave.

21.22 redis集群介紹

多個redis節點網絡互聯,數據共享
所有的節點都是一主一從(可以是多個從),其中從不提供服務,僅作為備用
不支持同時處理多個鍵(如mset/mget),因為redis需要把鍵均勻分布在各個節點上,並發量很高的情況下同時創建鍵值會降低性能並導致不可預測的行為。
支持在線增加、刪除節點
客戶端可以連任何一個主節點進行讀寫

21.23/21.24 redis集群搭建配置

場景設置:
兩臺機器,分別開啟三個Redis服務(端口)
A機器上三個端口7000,7002,7004,全部為主
B機器上三個端口7001,7003,7005,全部為從
兩臺機器上都要編譯安裝redis,然後編輯並復制3個不同的redis.conf,分別設置不同的端口號、dir等參數,還需要增加cluster相關參數,然後分別啟動6個redis服務
具體redis配置文件大家到https://coding.net/u/aminglinux/p/yuanke_centos7/git/tree/master/21NOSQL下載或者查看

安裝ruby2.2 (只需要一臺機器上運行)

yum -y groupinstall "Development Tools"
yum -y install gdbm-devel libdb4-devel libffi-devel libyaml libyaml-devel ncurses-devel openssl-devel readline-devel tcl-deve
cd /root/
mkdir -p rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}
wget http://cache.ruby-lang.org/pub/ruby/2.2/ruby-2.2.3.tar.gz -P rpmbuild/SOURCES
wget https://raw.githubusercontent.com/tjinjin/automate-ruby-rpm/master/ruby22x.spec -P rpmbuild/SPECS
rpmbuild -bb rpmbuild/SPECS/ruby22x.spec
yum -y localinstall rpmbuild/RPMS/x86_64/ruby-2.2.3-1.el7.centos.x86_64.rpm
gem install redis

21.25 redis集群操作

cp /usr/local/src/redis-4.0.1/src/redis-trib.rb /usr/bin/
redis-trib.rb create --replicas 1 192.168.133.130:7000 192.168.133.130:7002 192.168.133.130:7004 192.168.133.132:7001 192.168.133.132:7003 192.168.133.132:7005
redis-cli -c -h 192.168.133.130 -p 7000//-c說明以集群的方式登錄
任意一個節點都可以創建key,或者查看key(演示)
redis-trib.rb check 192.168.133.130:7000//檢測集群狀態
cluster nodes//列出節點
cluster info//查看集群信息
cluster meet ip port //添加節點
cluster forget node_id //移除某個節點
cluster replicate node_id//將當前節點設置為指定節點的從
cluster saveconfig//保存配置文件

擴展
redis 哨兵https://segmentfault.com/a/1190000002680804
http://www.cnblogs.com/jaycekon/p/6237562.html

2018-08-22(redis)