1、安裝redisphp
一、下載redis包html
wget http://download.redis.io/releases/redis-3.2.1.tar.gz
二、解壓redis包到/opt下node
tar -zxvf /home/redis-3.2.1.tar.gz -C /opt
三、安裝並測試redismysql
cd /opt/redis-3.2.1/src make && make install make test
備註:若make test報錯,提示安裝tcl,則進行tcl的安裝;程序員
若是想要安裝到制定的目錄,能夠在src下Makefile中修改 prefix? 的值.下面的腳本要一塊兒修改web
2、配置redisredis
一、複製並修改配置文檔算法
cp /opt/redis-3.2.1/redis.conf /etc/ vi /etc/redis.conf
#開啓redis遠程訪問 #將 bind 127.0.0.1改成 bind 0.0.0.0 #開啓redis守護進程 #根據需求,可配置redis是否進行持久化:修改save策略 (save "" 不持久化) #添加密碼訪問 requirepass password
二、將redis配置進系統服務sql
vi /etc/init.d/redis
/etc/init.d/redis內容以下數據庫
#chkconfig: 2345 90 10 # description: Redis is a persistent key-value database ########################### PATH=/usr/local/bin:/sbin:/usr/bin:/bin REDISPORT=6379 EXEC=/usr/local/bin/redis-server REDIS_CLI=/usr/local/bin/redis-cli PIDFILE=/var/run/redis_6379.pid CONF="/etc/redis.conf" PASSWORD=password case "$1" in start) if [ -f $PIDFILE ] then echo "$PIDFILE exists, process is already running or crashed" else echo "Starting Redis server..." $EXEC $CONF fi if [ "$?"="0" ] then echo "Redis is running..." fi ;; stop) if [ ! -f $PIDFILE ] then echo "$PIDFILE does not exist, process is not running" else PID=$(cat $PIDFILE) echo "Stopping ..." $REDIS_CLI -p $REDISPORT SHUTDOWN #如有密碼則加上密碼 #$REDIS_CLI -a $PASSWORD -p $REDISPORT SHUTDOWN while [ -x ${PIDFILE} ] do echo "Waiting for Redis to shutdown ..." sleep 1 done echo "Redis stopped" fi ;; restart|force-reload) ${0} stop ${0} start ;; *) echo "Usage: /etc/init.d/redis {start|stop|restart|force-reload}" >&2 exit 1 esac ##############################
#給redis文件加上執行權限 chmod +x /etc/init.d/redis
三、設置redis服務開機啓動
chkconfig redis on
四、在防火牆中開放redis端口
vi /etc/sysconfig/iptables #加入下面的端口配置 -A INPUT -p tcp -m state --state NEW -m tcp --dport 6379 -j ACCEPT #重啓防火牆 service iptables restart
五、啓動、關閉和重啓redis服務
service redis start service redis stop service redis restart
3、使用redis
#進入redis命令行 redis-cli -a password
四.基本命令
在線版:http://doc.redisfans.com/
下載地址html版:http://media.readthedocs.org/htmlzip/redis/latest/redis.zip
五.配置詳解
==基本配置
daemonize no 是否之後臺進程啓動
databases 16 建立database的數量(默認選中的是database 0)
save 900 1 #刷新快照到硬盤中,必須知足二者要求才會觸發,即900秒以後至少1個關鍵字發生變化。
save 300 10 #必須是300秒以後至少10個關鍵字發生變化。
save 60 10000 #必須是60秒以後至少10000個關鍵字發生變化。
stop-writes-on-bgsave-error yes #後臺存儲錯誤中止寫。
rdbcompression yes #使用LZF壓縮rdb文件。
rdbchecksum yes #存儲和加載rdb文件時校驗。
dbfilename dump.rdb #設置rdb文件名。
dir ./ #設置工做目錄,rdb文件會寫入該目錄。
==主從配置
slaveof <masterip> <masterport> 設爲某臺機器的從服務器
masterauth <master-password> 鏈接主服務器的密碼
slave-serve-stale-data yes # 當主從斷開或正在複製中,從服務器是否應答
slave-read-only yes #從服務器只讀
repl-ping-slave-period 10 #從ping主的時間間隔,秒爲單位
repl-timeout 60 #主從超時時間(超時認爲斷線了),要比period大
slave-priority 100 #若是master不能再正常工做,那麼會在多個slave中,選擇優先值最小的一個slave提高爲master,優先值爲0表示不能提高爲master。
repl-disable-tcp-nodelay no #主端是否合併數據,大塊發送給slave
slave-priority 100 從服務器的優先級,當主服掛了,會自動挑slave priority最小的爲主服
===安全
requirepass foobared # 須要密碼
rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 #若是公共環境,能夠重命名部分敏感命令 如config
===限制
maxclients 10000 #最大鏈接數
maxmemory <bytes> #最大使用內存
maxmemory-policy volatile-lru #內存到極限後的處理
volatile-lru -> LRU算法刪除過時key
allkeys-lru -> LRU算法刪除key(不區分過不過時)
volatile-random -> 隨機刪除過時key
allkeys-random -> 隨機刪除key(不區分過不過時)
volatile-ttl -> 刪除快過時的key
noeviction -> 不刪除,返回錯誤信息
#解釋 LRU ttl都是近似算法,能夠選N個,再比較最適宜T踢出的數據
maxmemory-samples 3
====日誌模式
appendonly no #是否僅要日誌
appendfsync no # 系統緩衝,統一寫,速度快
appendfsync always # 系統不緩衝,直接寫,慢,丟失數據少
appendfsync everysec #折衷,每秒寫1次
no-appendfsync-on-rewrite no #爲yes,則其餘線程的數據放內存裏,合併寫入(速度快,容易丟失的多)
auto-AOF-rewrite-percentage 100 當前aof文件是上次重寫是大N%時重寫
auto-AOF-rewrite-min-size 64mb aof重寫至少要達到的大小
====慢查詢
slowlog-log-slower-than 10000 #記錄響應時間大於10000微秒的慢查詢
slowlog-max-len 128 # 最多記錄128條
====服務端命令
time 返回時間戳+微秒
dbsize 返回key的數量
bgrewriteaof 重寫aof
bgsave 後臺開啓子進程dump數據
save 阻塞進程dump數據
lastsave
slaveof host port 作host port的從服務器(數據清空,複製新主內容)
slaveof no one 變成主服務器(原數據不丟失,通常用於主服失敗後)
flushdb 清空當前數據庫的全部數據
flushall 清空全部數據庫的全部數據(誤用了怎麼辦?)
shutdown [save/nosave] 關閉服務器,保存數據,修改AOF(若是設置)
slowlog get 獲取慢查詢日誌
slowlog len 獲取慢查詢日誌條數
slowlog reset 清空慢查詢
info []
config get 選項(支持*通配)
config set 選項 值
config rewrite 把值寫到配置文件
config restart 更新info命令的信息
debug object key #調試選項,看一個key的狀況
debug segfault #模擬段錯誤,讓服務器崩潰
object key (refcount|encoding|idletime)
monitor #打開控制檯,觀察命令(調試用)
client list #列出全部鏈接
client kill #殺死某個鏈接 CLIENT KILL 127.0.0.1:43501
client getname #獲取鏈接的名稱 默認nil
client setname "名稱" #設置鏈接名稱,便於調試
====鏈接命令===
auth 密碼 #密碼登錄(若是有密碼)
ping #測試服務器是否可用
echo "some content" #測試服務器是否正常交互
select 0/1/2... #選擇數據庫
quit #退出鏈接
Redis is an open source, BSD licensed, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.
redis是開源,BSD許可,高級的key-value存儲系統.
能夠用來存儲字符串,哈希結構,鏈表,集合,所以,經常使用來提供數據結構服務.
1: redis能夠用來作存儲(storge), 而memccached是用來作緩存(cache)
這個特色主要由於其有」持久化」的功能.
2: 存儲的數據有」結構」,對於memcached來講,存儲的數據,只有1種類型--」字符串」,
而redis則能夠存儲字符串,鏈表,哈希結構,集合,有序集合.
make PREFIX=/usr/local/redis install
注: PREFIX要大寫
redis-benchmark 性能測試工具
redis-check-aof 日誌文件檢測工(好比斷電形成日誌損壞,能夠檢測並修復)
redis-check-dump 快照文件檢測工具,效果類上
redis-cli 客戶端
redis-server 服務端
/path/to/redis/bin/redis-server ./path/to/conf-file
例:[root@localhost redis]# ./bin/redis-server ./redis.conf
#/path/to/redis/bin/redis-cli [-h localhost -p 6379 ]
編輯conf配置文件,修改以下內容;
daemonize yes
做用: 刪除1個或多個鍵
返回值: 不存在的key忽略掉,返回真正刪除的key的數量
做用: 給key賦一個新的key名
注:若是newkey已存在,則newkey的原值被覆蓋
做用: 把key更名爲newkey
返回: 發生修改返回1,未發生修改返回0
注: nx--> not exists, 即, newkey不存在時,做更名動做
redis 127.0.0.1:6379[1]> select 2
OK
redis 127.0.0.1:6379[2]> keys *
(empty list or set)
redis 127.0.0.1:6379[2]> select 0
OK
redis 127.0.0.1:6379> keys *
1) "name"
2) "cc"
3) "a"
4) "b"
redis 127.0.0.1:6379> move cc 2
(integer) 1
redis 127.0.0.1:6379> select 2
OK
redis 127.0.0.1:6379[2]> keys *
1) "cc"
redis 127.0.0.1:6379[2]> get cc
"3"
(注意: 一個redis進程,打開了不止一個數據庫, 默認打開16個數據庫,從0到15編號,
若是想打開更多數據庫,能夠從配置文件修改)
在redis裏,容許模糊查詢key
有3個通配符 *, ? ,[]
*: 通配任意多個字符
?: 通配單個字符
[]: 通配括號內的某1個字符
redis 127.0.0.1:6379> flushdb
OK
redis 127.0.0.1:6379> keys *
(empty list or set)
redis 127.0.0.1:6379> mset one 1 two 2 three 3 four 4
OK
redis 127.0.0.1:6379> keys o*
1) "one"
redis 127.0.0.1:6379> key *o
(error) ERR unknown command 'key'
redis 127.0.0.1:6379> keys *o
1) "two"
redis 127.0.0.1:6379> keys ???
1) "one"
2) "two"
redis 127.0.0.1:6379> keys on?
1) "one"
redis 127.0.0.1:6379> set ons yes
OK
redis 127.0.0.1:6379> keys on[eaw]
1) "one"
判斷key是否存在,返回1/0
返回key存儲的值的類型
有string,link,set,order set, hash
做用: 查詢key的生命週期
返回: 秒數
注:對於不存在的key或已過時的key/不過時的key,都返回-1
Redis2.8中,對於不存在的key,返回-2
做用: 設置key的生命週期,以秒爲單位
同理:
pexpire key 毫秒數, 設置生命週期
pttl key, 以毫秒返回生命週期
做用: 把指定key置爲永久有效
如: set a 1 ex 10 , 10秒有效
Set a 1 px 9000 , 9秒有效
注: 若是ex,px同時寫,之後面的有效期爲準
如 set a 1 ex 100 px 9000, 實際有效期是9000毫秒
nx: 表示key不存在時,執行操做
xx: 表示key存在時,執行操做
例: mset key1 v1 key2 v2 ....
做用:獲取key的值
做用:獲取多個key的值
做用:把字符串的offset偏移字節,改爲value
redis 127.0.0.1:6379> set greet hello
OK
redis 127.0.0.1:6379> setrange greet 2 x
(integer) 5
redis 127.0.0.1:6379> get greet
"hexlo"
注意: 若是偏移量>字符長度, 該字符自動補0x00
redis 127.0.0.1:6379> setrange greet 6 !
(integer) 7
redis 127.0.0.1:6379> get greet
"heyyo\x00!"
做用: 把value追加到key的原值上
做用: 是獲取字符串中 [start, stop]範圍的值
注意: 對於字符串的下標,左數從0開始,右數從-1開始
redis 127.0.0.1:6379> set title 'chinese'
OK
redis 127.0.0.1:6379> getrange title 0 3
"chin"
redis 127.0.0.1:6379> getrange title 1 -2
"hines"
注意:
1: start>=length, 則返回空字符串
2: stop>=length,則截取至字符結尾
3: 若是start 所處位置在stop右邊, 返回空字符串
做用: 獲取並返回舊值,設置新值
redis 127.0.0.1:6379> set cnt 0
OK
redis 127.0.0.1:6379> getset cnt 1
"0"
redis 127.0.0.1:6379> getset cnt 2
"1"
做用: 指定的key的值加1,並返回加1後的值
注意:
1:不存在的key當成0,再incr操做
2: 範圍爲64有符號
redis 127.0.0.1:6379> incrby age 90
(integer) 92
redis 127.0.0.1:6379> incrbyfloat age 3.5
"95.5"
redis 127.0.0.1:6379> set age 20
OK
redis 127.0.0.1:6379> decr age
(integer) 19
redis 127.0.0.1:6379> decrby age 3
(integer) 16
做用:獲取值的二進制表示,對應位上的值(從左,從0編號)
redis 127.0.0.1:6379> set char A
OK
redis 127.0.0.1:6379> getbit char 1
(integer) 1
redis 127.0.0.1:6379> getbit char 2
(integer) 0
redis 127.0.0.1:6379> getbit char 7
(integer) 1
設置offset對應二進制位上的值
返回: 該位上的舊值
注意:
1:若是offset過大,則會在中間填充0,
2: offset最大大到多少
3:offset最大2^32-1,可推出最大的的字符串爲512M
對key1,key2..keyN做operation,並將結果保存到 destkey 上。
operation 能夠是 AND 、 OR 、 NOT 、 XOR
redis 127.0.0.1:6379> setbit lower 7 0
(integer) 0
redis 127.0.0.1:6379> setbit lower 2 1
(integer) 0
redis 127.0.0.1:6379> get lower
" "
redis 127.0.0.1:6379> set char Q
OK
redis 127.0.0.1:6379> get char
"Q"
redis 127.0.0.1:6379> bitop or char char lower
(integer) 1
redis 127.0.0.1:6379> get char
"q"
注意: 對於NOT操做, key不能多個
做用: 把值插入到連接頭部
做用: 返回並刪除鏈表尾元素
做用: 返回鏈表中[start ,stop]中的元素
規律: 左數從0開始,右數從-1開始
做用: 從key鏈表中刪除 value值
注: 刪除count的絕對值個value後結束
Count>0 從表頭刪除
Count<0 從表尾刪除
做用: 剪切key對應的連接,切[start,stop]一段,並把該段從新賦給key
做用: 返回index索引上的值,
如 lindex key 2
做用:計算連接表的元素個數
redis 127.0.0.1:6379> llen task
(integer) 3
redis 127.0.0.1:6379>
做用: 在key鏈表中尋找’search’,並在search值以前|以後,.插入value
注: 一旦找到一個search後,命令就結束了,所以不會插入多個value
做用: 把source的尾部拿出,放在dest的頭部,
並返回 該單元值
場景: task + bak 雙鏈表完成安全隊列
Task列表 bak列表
|
|
|
|
|
|
業務邏輯:
1:Rpoplpush task bak
2:接收返回值,並作業務處理
3:若是成功,rpop bak 清除任務. 如不成功,下次從bak表裏取任務
做用:等待彈出key的尾/頭元素,
Timeout爲等待超時時間
若是timeout爲0,則一直等待
場景: 長輪詢Ajax,在線聊天時,可以用到
場景: 1億個用戶, 每一個用戶 登錄/作任意操做 ,記爲 今天活躍,不然記爲不活躍
每週評出: 有獎活躍用戶: 連續7天活動
每個月評,等等...
思路:
Userid dt active
1 2013-07-27 1
1 2013-0726 1
若是是放在表中, 1:表急劇增大,2:要用group ,sum運算,計算較慢
用: 位圖法 bit-map
Log0721: ‘011001...............0’
......
log0726 : ‘011001...............0’
Log0727 : ‘0110000.............1’
1: 記錄用戶登錄:
天天按日期生成一個位圖, 用戶登錄後,把user_id位上的bit值置爲1
2: 把1周的位圖 and 計算,
位上爲1的,便是連續登錄的用戶
redis 127.0.0.1:6379> setbit mon 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit mon 3 1
(integer) 0
redis 127.0.0.1:6379> setbit mon 5 1
(integer) 0
redis 127.0.0.1:6379> setbit mon 7 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit thur 3 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 5 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 8 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit wen 3 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 4 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 6 1
(integer) 0
redis 127.0.0.1:6379> bitop and res mon feb wen
(integer) 12500001
如上例,優勢:
1: 節約空間, 1億人天天的登錄狀況,用1億bit,約1200WByte,約10M 的字符就能表示
2: 計算方便
集合的性質: 惟一性,無序性,肯定性
注: 在string和link的命令中,能夠經過range 來訪問string中的某幾個字符或某幾個元素
但,由於集合的無序性,沒法經過下標或範圍來訪問部分元素.
所以想看元素,要麼隨機先一個,要麼全選
做用: 往集合key中增長元素
做用: 刪除集合中集爲 value1 value2的元素
返回值: 忽略不存在的元素後,真正刪除掉的元素的個數
做用: 返回並刪除集合中key中1個隨機元素
隨機--體現了無序性
做用: 返回集合key中,隨機的1個元素.
做用: 判斷value是否在key集合中
是返回1,否返回0
做用: 返回集中中全部的元素
做用: 返回集合中元素的個數
做用:把source中的value刪除,並添加到dest集合中
做用: 求出key1 key2 key3 三個集合中的交集,並返回
redis 127.0.0.1:6379> sadd s1 0 2 4 6
(integer) 4
redis 127.0.0.1:6379> sadd s2 1 2 3 4
(integer) 4
redis 127.0.0.1:6379> sadd s3 4 8 9 12
(integer) 4
redis 127.0.0.1:6379> sinter s1 s2 s3
1) "4"
redis 127.0.0.1:6379> sinter s3 s1 s2
1) "4"
做用: 求出key1 key2 key3 三個集合中的交集,並賦給dest
做用: 求出key1 key2 keyn的並集,並返回
做用: 求出key1與key2 key3的差集
即key1-key2-key3
zadd key score1 value1 score2 value2 ..
添加元素
redis 127.0.0.1:6379> zadd stu 18 lily 19 hmm 20 lilei 21 lilei
(integer) 3
做用: 刪除集合中的元素
做用: 按照socre來刪除元素,刪除score在[min,max]之間的
redis 127.0.0.1:6379> zremrangebyscore stu 4 10
(integer) 2
redis 127.0.0.1:6379> zrange stu 0 -1
1) "f"
做用: 按排名刪除元素,刪除名次在[start,end]之間的
redis 127.0.0.1:6379> zremrangebyrank stu 0 1
(integer) 2
redis 127.0.0.1:6379> zrange stu 0 -1
1) "c"
2) "e"
3) "f"
4) "g"
查詢member的排名(升續 0名開始)
查詢 member的排名(降續 0名開始)
把集合排序後,返回名次[start,stop]的元素
默認是升續排列
Withscores 是把score也打印出來
做用:把集合降序排列,取名字[start,stop]之間的元素
做用: 集合(升續)排序後,取score在[min,max]內的元素,
並跳過 offset個, 取出N個
redis 127.0.0.1:6379> zadd stu 1 a 3 b 4 c 9 e 12 f 15 g
(integer) 6
redis 127.0.0.1:6379> zrangebyscore stu 3 12 limit 1 2 withscores
1) "c"
2) "4"
3) "e"
4) "9"
返回元素個數
返回[min,max] 區間內元素的數量
[WEIGHTS weight [weight ...]]
[AGGREGATE SUM|MIN|MAX]
求key1,key2的交集,key1,key2的權重分別是 weight1,weight2
聚合方法用: sum |min|max
聚合的結果,保存在dest集合內
注意: weights ,aggregate如何理解?
答: 若是有交集, 交集元素又有socre,score怎麼處理?
Aggregate sum->score相加 , min 求最小score, max 最大score
另: 能夠經過weigth設置不一樣key的權重, 交集時,socre * weights
詳見下例
redis 127.0.0.1:6379> zadd z1 2 a 3 b 4 c
(integer) 3
redis 127.0.0.1:6379> zadd z2 2.5 a 1 b 8 d
(integer) 3
redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2
(integer) 2
redis 127.0.0.1:6379> zrange tmp 0 -1
1) "b"
2) "a"
redis 127.0.0.1:6379> zrange tmp 0 -1 withscores
1) "b"
2) "4"
3) "a"
4) "4.5"
redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 aggregate sum
(integer) 2
redis 127.0.0.1:6379> zrange tmp 0 -1 withscores
1) "b"
2) "4"
3) "a"
4) "4.5"
redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 aggregate min
(integer) 2
redis 127.0.0.1:6379> zrange tmp 0 -1 withscores
1) "b"
2) "1"
3) "a"
4) "2"
redis 127.0.0.1:6379> zinterstore tmp 2 z1 z2 weights 1 2
(integer) 2
redis 127.0.0.1:6379> zrange tmp 0 -1 withscores
1) "b"
2) "5"
3) "a"
4) "7"
做用: 把key中 filed域的值設爲value
注:若是沒有field域,直接添加,若是有,則覆蓋原field域的值
做用: 設置field1->N 個域, 對應的值是value1->N
(對應PHP理解爲 $key = array(file1=>value1, field2=>value2 ....fieldN=>valueN))
做用: 返回key中field域的值
做用: 返回key中field1 field2 fieldN域的值
做用:返回key中,全部域與其值
做用: 刪除key中 field域
做用: 返回key中元素的數量
做用: 判斷key中有沒有field域
做用: 是把key中的field域的值增加整型值value
做用: 是把key中的field域的值增加浮點值value
做用: 返回key中全部的field
做用: 返回key中全部的value
Redis支持簡單的事務
Redis與 mysql事務的對比
|
Mysql |
Redis |
開啓 |
start transaction |
muitl |
語句 |
普通sql |
普通命令 |
失敗 |
rollback 回滾 |
discard 取消 |
成功 |
commit |
exec |
注: rollback與discard 的區別
若是已經成功執行了2條語句, 第3條語句出錯.
Rollback後,前2條的語句影響消失.
Discard只是結束本次事務,前2條語句形成的影響仍然還在
注:
在mutil後面的語句中, 語句出錯可能有2種狀況
1: 語法就有問題,
這種,exec時,報錯, 全部語句得不到執行
2: 語法自己沒錯,但適用對象有問題. 好比 zadd 操做list對象
Exec以後,會執行正確的語句,並跳過有不適當的語句.
(若是zadd操做list這種事怎麼避免? 這一點,由程序員負責)
思考:
我正在買票
Ticket -1 , money -100
而票只有1張, 若是在我multi以後,和exec以前, 票被別人買了---即ticket變成0了.
我該如何觀察這種情景,並再也不提交
悲觀的想法:
世界充滿危險,確定有人和我搶, 給 ticket上鎖, 只有我能操做. [悲觀鎖]
樂觀的想法:
沒有那麼人和我搶,所以,我只須要注意,
--有沒有人更改ticket的值就能夠了 [樂觀鎖]
Redis的事務中,啓用的是樂觀鎖,只負責監測key沒有被改動.
具體的命令---- watch命令
例:
redis 127.0.0.1:6379> watch ticket
OK
redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> decr ticket
QUEUED
redis 127.0.0.1:6379> decrby money 100
QUEUED
redis 127.0.0.1:6379> exec
(nil) // 返回nil,說明監視的ticket已經改變了,事務就取消了.
redis 127.0.0.1:6379> get ticket
"0"
redis 127.0.0.1:6379> get money
"200"
做用:監聽key1 key2..keyN有沒有變化,若是有變, 則事務取消
做用: 取消全部watch監聽
使用辦法:
訂閱端: Subscribe 頻道名稱
發佈端: publish 頻道名稱 發佈內容
客戶端例子:
redis 127.0.0.1:6379> subscribe news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1
1) "message"
2) "news"
3) "good good study"
1) "message"
2) "news"
3) "day day up"
服務端例子:
redis 127.0.0.1:6379> publish news 'good good study'
(integer) 1
redis 127.0.0.1:6379> publish news 'day day up'
(integer) 1
save 900 1 // 900內,有1條寫入,則產生快照
save 300 1000 // 若是300秒內有1000次寫入,則產生快照
save 60 10000 // 若是60秒內有10000次寫入,則產生快照
(這3個選項都屏蔽,則rdb禁用)
stop-writes-on-bgsave-error yes // 後臺備份進程出錯時,主進程停不中止寫入?
rdbcompression yes // 導出的rdb文件是否壓縮
Rdbchecksum yes // 導入rbd恢復時數據時,要不要檢驗rdb的完整性
dbfilename dump.rdb //導出來的rdb文件名
dir ./ //rdb的放置路徑
appendonly no # 是否打開 aof日誌功能 appendfsync always # 每1個命令,都當即同步到aof. 安全,速度慢 appendfsync everysec # 折衷方案,每秒寫1次 appendfsync no # 寫入工做交給操做系統,由操做系統判斷緩衝區大小,統一寫入到aof. 同步頻率低,速度快, no-appendfsync-on-rewrite yes: # 正在導出rdb快照的過程當中,要不要中止同步aof auto-aof-rewrite-percentage 100 #aof文件大小比起上次重寫時的大小,增加率100%時,重寫 auto-aof-rewrite-min-size 64mb #aof文件,至少超過64M時,重寫
注: 在dump rdb過程當中,aof若是中止同步,會不會丟失?
答: 不會,全部的操做緩存在內存的隊列裏, dump完成後,統一操做.
注: aof重寫是指什麼?
答: aof重寫是指把內存中的數據,逆化成命令,寫入到.aof日誌裏.以解決 aof日誌過大的問題.
問: 若是rdb文件,和aof文件都存在,優先用誰來恢復數據?
答: aof
問: 2種是否能夠同時用?
答: 能夠,並且推薦這麼作
問: 恢復時rdb和aof哪一個恢復的快
答: rdb快,由於其是數據的內存映射,直接載入到內存,而aof是命令,須要逐條執行
redis 服務器端命令
redis 127.0.0.1:6380> time ,顯示服務器時間 , 時間戳(秒), 微秒數
1) "1375270361"
2) "504511"
redis 127.0.0.1:6380> dbsize // 當前數據庫的key的數量
(integer) 2
redis 127.0.0.1:6380> select 2
OK
redis 127.0.0.1:6380[2]> dbsize
(integer) 0
redis 127.0.0.1:6380[2]>
BGREWRITEAOF 後臺進程重寫AOF
BGSAVE 後臺保存rdb快照
SAVE 保存rdb快照
LASTSAVE 上次保存時間
Slaveof master-Host port , 把當前實例設爲master的slave
Flushall 清空全部庫全部鍵
Flushdb 清空當前庫全部鍵
Showdown [save/nosave]
注: 若是不當心運行了flushall, 當即 shutdown nosave ,關閉服務器
而後 手工編輯aof文件, 去掉文件中的 「flushall 」相關行, 而後開啓服務器,就能夠導入回原來數據.
若是,flushall以後,系統剛好bgrewriteaof了,那麼aof就清空了,數據丟失.
Slowlog 顯示慢查詢
注:多慢才叫慢?
答: 由slowlog-log-slower-than 10000 ,來指定,(單位是微秒)
服務器儲存多少條慢查詢的記錄?
答: 由 slowlog-max-len 128 ,來作限制
Info [Replication/CPU/Memory..]
查看redis服務器的信息
Config get 配置項
Config set 配置項 值 (特殊的選項,不容許用此命令設置,如slave-of, 須要用單獨的slaveof命令來設置)
1: 內存
# Memory
used_memory:859192 數據結構的空間
used_memory_rss:7634944 實佔空間
mem_fragmentation_ratio:8.89 前2者的比例,1.N爲佳,若是此值過大,說明redis的內存的碎片化嚴重,能夠導出再導入一次.
2: 主從複製
# Replication
role:slave
master_host:192.168.1.128
master_port:6379
master_link_status:up
3:持久化
# Persistence
rdb_changes_since_last_save:0
rdb_last_save_time:1375224063
4: fork耗時
#Status
latest_fork_usec:936 上次導出rdb快照,持久化花費微秒
注意: 若是某實例有10G內容,導出須要2分鐘,
每分鐘寫入10000次,致使不斷的rdb導出,磁盤始處於高IO狀態.
5: 慢日誌
config get/set slowlog-log-slower-than
CONFIG get/SET slowlog-max-len
slowlog get N 獲取慢日誌
運行時更改master-slave
修改一臺slave(設爲A)爲new master
1) 命令該服務不作其餘redis服務的slave
命令: slaveof no one
2) 修改其readonly爲yes
其餘的slave再指向new master A
1) 命令該服務爲new master A的slave
命令格式 slaveof IP port
監控工具 sentinel
Sentinel不斷與master通訊,獲取master的slave信息.
監聽master與slave的狀態
若是某slave失效,直接通知master去除該slave.
若是master失效,,是按照slave優先級(可配置), 選取1個slave作 new master,把其餘slave--> new master
疑問: sentinel與master通訊,若是某次由於master IO操做頻繁,致使超時,此時,認爲master失效,很武斷.
解決: sentnel容許多個實例看守1個master, 當N臺(N可設置)sentinel都認爲master失效,才正式失效.
Sentinel選項配置
port 26379 # 端口
sentinel monitor mymaster 127.0.0.1 6379 2 ,
給主機起的名字(不重便可),
當2個sentinel實例都認爲master失效時,正式失效
sentinel down-after-milliseconds mymaster 30000 多少毫秒後鏈接不到master認爲斷開
sentinel can-failover mymaster yes #是否容許sentinel修改slave->master. 如爲no,則只能監控,無權修改./
sentinel parallel-syncs mymaster 1 , 一次性修改幾個slave指向新的new master.
sentinel client-reconfig-script mymaster /var/redis/reconfig.sh ,# 在從新配置new master,new slave過程,能夠觸發的腳本
create table book (
bookid int,
title char(20)
)engine myisam charset utf8;
insert into book values
(5 , 'PHP聖經'),
(6 , 'ruby實戰'),
(7 , 'mysql運維')
(8, 'ruby服務端編程');
create table tags (
tid int,
bookid int,
content char(20)
)engine myisam charset utf8;
insert into tags values
(10 , 5 , 'PHP'),
(11 , 5 , 'WEB'),
(12 , 6 , 'WEB'),
(13 , 6 , 'ruby'),
(14 , 7 , 'database'),
(15 , 8 , 'ruby'),
(16 , 8 , 'server');
# 既有web標籤,又有PHP,同時還標籤的書,要用鏈接查詢
select * from tags inner join tags as t on tags.bookid=t.bookid
where tags.content='PHP' and t.content='WEB';
用kv 來存儲
set book:5:title 'PHP聖經'
set book:6:title 'ruby實戰'
set book:7:title 'mysql運難'
set book:8:title ‘ruby server’
sadd tag:PHP 5
sadd tag:WEB 5 6
sadd tag:database 7
sadd tag:ruby 6 8
sadd tag:SERVER 8
查: 既有PHP,又有WEB的書
Sinter tag:PHP tag:WEB #查集合的交集
查: 有PHP或有WEB標籤的書
Sunin tag:PHP tag:WEB
查:含有ruby,不含WEB標籤的書
Sdiff tag:ruby tag:WEB #求差集
1: 把表名轉換爲key前綴 如, tag:
2: 第2段放置用於區分區key的字段--對應mysql中的主鍵的列名,如userid
3: 第3段放置主鍵值,如2,3,4...., a , b ,c
4: 第4段,寫要存儲的列名
用戶表 user , 轉換爲key-value存儲 |
|||
userid |
username |
passworde |
|
9 |
Lisi |
1111111 |
lisi@163.com |
set user:userid:9:username lisi
set user:userid:9:password 111111
set user:userid:9:email lisi@163.com
keys user:userid:9*
2 注意:
在關係型數據中,除主鍵外,還有可能其餘列也步驟查詢,
如上表中, username 也是極頻繁查詢的,每每這種列也是加了索引的.
轉換到k-v數據中,則也要相應的生成一條按照該列爲主的key-value
Set user:username:lisi:uid 9
這樣,咱們能夠根據username:lisi:uid ,查出userid=9,
再查user:9:password/email ...
完成了根據用戶名來查詢用戶信息
php-redis擴展編譯
1: 到pecl.php.net 搜索redis
2: 下載stable版(穩定版)擴展
3: 解壓,
4: 執行/php/path/bin/phpize (做用是檢測PHP的內核版本,併爲擴展生成相應的編譯配置)
5: configure --with-php-config=/php/path/bin/php-config
6: make && make install
引入編譯出的redis.so插件
1: 編輯php.ini
2: 添加
// get instance
$redis = new Redis();
// connect to redis server
$redis->open('localhost',6380);
$redis->set('user:userid:9:username','wangwu');
var_dump($redis->get('user:userid:9:username'));
微博項目的key設計
全局相關的key:
表名 |
global |
|
列名 |
操做 |
備註 |
Global:userid |
incr |
產生全局的userid |
Global:postid |
Incr |
產生全局的postid |
用戶相關的key(表)
表名 |
user |
||
Userid |
Username |
Password |
Authsecret |
3 |
Test3 |
1111111 |
#U*Q(%_ |
在redis中,變成如下幾個key
Key前綴 |
user |
||
User:Userid:* |
User:userid:*Username |
User:userid:*Password |
User:userid:*:Authsecret |
User:userid:3 |
User:userid:3:Test3 |
User:userid:3:1111111 |
User:userid:3:#U*Q(%_ |
微博相關的表設計
表名 |
post |
|
|
|
Postid |
Userid |
Username |
Time |
Content |
4 |
2 |
Lisi |
1370987654f |
測試內容 |
微博在redis中,與表設計對應的key設計
Key前綴 |
post |
|
|
|
Post:Postid:* |
Post:postid:*Userid |
Post:postid:*:Username |
Post:postid:*:Time |
Post:postid:*:Content |
4 |
2 |
Lisi |
1370987654f |
測試內容 |
關注表: following
Following:$userid -->
粉絲表
Follower:$userid --->
推送表:revicepost
3 |
4 |
7 |
|
|
|
=================拉模型,改進=====================
拉取表
3 |
4 |
7 |
|
|
|
問: 上次我拉取了 A->5,67,三條微博, 下次刷新home.php, 從>7的微博開始拉取
解決: 拉取時,設定一個lastpull時間點, 下次拉取時,取>lastpull的微博
問: 有不少關注人,如何取?
解決: 循環本身的關注列表,逐個取他們的新微博
問: 取出來以後放在哪兒?
答: pull:$userid的連接裏
問: 若是我的中心,只有前1000條
答: ltrim,只取前1000條
問: 若是我關注 A,B兩人, 從2人中,各取3條最新信息
,這3+3條信息, 從時間上,是交錯的, 如何按時間排序?
答: 咱們發佈時, 是發佈的hash結構, 不能按時間來排序.
解決: 同步時,取微博後,記錄本次取的微博的最大id,
下次同步時,只取比最大id更大的微博
Time taken for tests: 32.690 seconds
Complete requests: 20000
Failed requests: 0
Write errors: 0
Non-2xx responses: 20000
Total transferred: 13520000 bytes
Total POSTed: 5340000
HTML transferred: 9300000 bytes
Requests per second: 611.80 [#/sec] (mean)
Time per request: 81.726 [ms] (mean)
Time per request: 1.635 [ms] (mean, across all concurrent requests)
Transfer rate: 403.88 [Kbytes/sec] received
159.52 kb/s sent
563.41 kb/s total
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.9 0 19
Processing: 14 82 8.4 81 153
Waiting: 4 82 8.4 80 153
Total: 20 82 8.2 81 153
Percentage of the requests served within a certain time (ms)
50% 81
66% 84
75% 86
80% 88
90% 93
95% 96
98% 100
99% 103
100% 153 (longest request)
測試結果:
50個併發, 20000次請求, 虛擬下,未作特殊優化
每次請求redis寫操做6次.
30+秒左右完成.
平均每秒發佈700條微博, 4000次redis寫入.
後臺定時任務,迴歸冷數據入mysql
Redis配置文件
daemonize yes # redis是否之後臺進程運行
Requirepass 密碼 # 配置redis鏈接的密碼
注:配置密碼後,客戶端連上服務器,須要先執行受權命令
# auth 密碼