redis redis的安裝一 安裝的準備 首先得買一個伺服器(我買的阿裡雲ecs輕量級); 再下載遠程客戶端(我用的Xshell,Xftp); 打開Xftp將下載好得redis壓縮包傳輸Xftp中,在進入Xshell中Linux命令安裝; rides安裝 下載地址:https://redis.io ...
redis
redis的安裝一
安裝的準備
首先得買一個伺服器(我買的阿裡雲ecs輕量級);
再下載遠程客戶端(我用的Xshell,Xftp);
打開Xftp將下載好得redis壓縮包傳輸Xftp中,在進入Xshell中Linux命令安裝;
rides安裝
下載地址:https://redis.io/
安裝:
1,Linux進入redis所在目錄;
2,執行命令:tar -zxvf redis-3.2.10.tar.gz //個人建議將軟體安裝在/usr/local目錄下,執行命令:tar -zxvf redis-3.2.10.tar.gz -C /usr/local/redis,當然解壓完了move也可以;
3,進入解壓後的目錄進行編譯,cd redis-3.2.10. 執行命令:make ,make命令後可能報錯,如果報錯,解決如下:
報錯一:那可能是沒有gcc (linux下的一個編譯器,是c,c++程式的編譯器)
使用命令yum進行安裝,yum -y install gcc
報錯二:error:jemalloc/jemalloc.h:No such file or disectoty //可能找不到c語言中的頭文件
執行 make MALLOC = libc
4,安裝完gcc之後,make distclean 清理下上次make後產生的文件,再make
redis啟動:
方式一:前端啟動模式,前端模式啟動的缺點是ssh命令視窗關閉則redis-server程式結束,而且當前命令視窗處於一種阻塞狀態,想要執行其它命令需要重新開啟一個新命令視窗
執行命令:cd /usr/local/redis/redis-3.2.10/bin
再執行命令:./redis-server
//ps -f | grep redis 查看進程 kill pid(進程號) 殺掉進程
方式二:後臺啟動模式,./redis-server & //建議後臺啟動
後臺啟動並輸出日誌到 nohup.out 文件:nohup /usr/local/redis-3.2.10/src/-server &
再回車確定
ls查看文件會發現出現一個nohup.out文件
cat nohup.out 就會將日誌打在此文件中
redis關閉:./redis -cli shutdown
redis的安裝二
https://www.jb51.net/article/146751.htm
redis客戶端
redis命令行客戶端:redis -cli (./redis -cli -h 127.0.0.1 -p 6379) //redis自帶基於命令行得redis客戶端
Redis Desktop Manager(遠程客戶端): //要下載
遠程連接redis需要修改redis主目錄下的redis.conf配置文件:
1,bind ip 綁定ip註釋掉
2,protected-mode yes 保護模式改為no;
可以進入目錄配置文件改,也可以命令改,命令如下:
進入目錄:cd /usr /local /redis-3.2.10 /
進入文件:vim redis.conf 回車確定
註釋bind ip;protected-mode yes 保護模式改為no;回車確定
ps -ef | grep redis //查看進程
kill pid //殺掉當前進程再重啟
nohup /usr/local/redis-3.2.10/src/redis - server /usr/local/redis-3.2.10/redis.conf & //重啟進程並打出日誌文件
進入下載好的遠程客戶端:
Connection 連接自己的遠程伺服器地址; //這裡一定要填自己的遠程ip,不能填本地
ok
phpRedisAdmin(遠程客戶端):
需要安裝php運行環境
php開發自行下載xampp
redis編程客戶端:
redis的Java客戶端:
jedis:
jedis源碼:https://github.com/xetorhio/jedis
api文檔:http://xetorthio.geihub.io/jedis/
redis的使用
基礎命令:
1, ./redis -cli //啟動
輸入ping,redis會返回PONG表示服務運行正常
2,redis預設16個庫,但是可以再redis.conf中修改。 //可進文件改,也可命令改
進入文件:vim redis.conf 回車確定
找到databases 16 //可改
3,redis預設使用0號庫,select db //切換庫 例:select 2
4,刪除
刪除所有庫數據 : flushall
刪除當前庫數據 : flushdb
5,獲取redis的所有配置 :config get *
6,退出連接:exit / quit
7,查看當前資料庫中key的數目:dbsize
8,查看redis伺服器的統計信息:info
命令與使用文檔:
命令:
key命令
字元串類型 :string
哈希類型 :hash
列表類型 :list
集合類型 :set
有序集合類型 :zset(sorted set)
文檔:
中文:https://redis.io/commands
英文:https://redisdoc.com/
redis常用命令 :
keys * //列出所有key
exists key //檢查某個key是否存在
set key value //存入key值 例:set k1 v1
move key db //將當前的key移動到給定的庫db中,例:move k1 2
expire key seconds //設置key值過期時間 例:expire k1 8
ttl key (time to live) //查看是否過期,-1永不過期,-2 已過期或key不存在
type key //查看key所存儲值得類型
del key //刪除key
redis更多使用方法請移步菜鳥教程:https://www.runoob.com/redis/redis-install.html
redis5中數據類型命令
字元串類型 String(可以存儲任何形式的字元串)
set key value 將字元串值value設置到key中
get key 獲取key中的value
incr key 將key中存儲的數字加一,若key不存在,key得值先被初始化為0,再執行incr操作(只對存儲的數字有用)
decr key 將key中存儲的數字減一,若key不存在,key得值先被初始化為0,再執行incr操作(只對存儲的數字有用)
setex key seconds value 設置key值及過期時間(set expire)
setnx key value 給無值或者不存在的key給值,有值則不設置值
getset key value 給key設置新值並返回舊值
strlen key 返回key所存儲字元串長度
append key value 若key存在且為字元串,則追加(跟jquery一樣);key不存在將追加的設為新值
incrby key increment 將key所存儲的值加上增質量(自定義量),若key不存在,則key的值初始化為0,再執行incrby
decrby key increment 將key所存儲的值減去增質量(自定義量),若key不存在,則key的值初始化為0,再執行incrby
getrange key start end 截取key中字元串值,從star開始,end結束(類似subString)
setrang key offset value 從字元串指定位置替換value,例:k1值為helloworld,執行setrang k1 5(第五個位置) redis 則輸出:helloredis
mset key1 value key2 value2 ... 同時設置多個key-value
mget key1 key2 keyn ... 同時獲取多個key-value
msetnx key1 value key2 value2 ... 同時設置多個key-value,當且僅當所有給定key都不存在時才能設置成功,有一個key存在值都不行
哈希類型hash(String類型的映射,適合存儲對象)
hset key field value 將哈希表key中的域field的值設置為value 例:hset k1 id 1001
hget key field 取值 例:hget k1 id
hmset key1 field value ... 同時設置多個值 例:hmset k2 id 1002 name likauhua age 10 pwd 123 ...
hmget key field ... 同時取多個值 例:hmget k2 id name age
hgetall key 查詢哈希表key里所有值
hdel key 刪除哈希表key中一個或多個指定值field
hkeys key 查看哈希表key中所有field域(查詢所有欄位)
hvals key 查看哈希表key中所有域的值(欄位所對應的值)
type key 查案key存儲的數據類型
hlen key 查看哈希表key中域field的個數(欄位個數)
hexists key 查看哈希表key中,給定域field是否存在(欄位是否存在還)例:hexists k1 id
hincrby key field increment 為哈希表key中的域的值加上增量 例:hincrby k1 id 5
hincrbyfloat key field increment 為哈希表key中的域的值加浮點數上增量
hsetnx key field value 將哈希表key中的域field的值設為value,當且僅當field不存在時才設置,否則不設置 例:hsetnx k1 age(這個欄位不存在時才能設置) 18
列表類型list(簡單的字元串列表,按照插入排序,元素可重覆)
lpush key value1 value2 value3 將一個或多個值value插入到列表key的表頭(最左邊) 例:lpush k1 1 2 3 4 5
rpush key value1 value2 value3 將一個或多個值value插入到列表key的表尾(最右邊) 例:lpush k1 7 8 9 10 11
lrange key start stop 獲取表key中指定區間內元素,0為第一元素,-1為倒數第一元素。 例:lrange key 0 -1 (區間所有元素)
lpop key 從左邊獲取列表key的第一個元素,並將該元素移除
rpop key 從右邊獲取列表key的第一個元素,並將該元素移除
lindex key index 獲取列表key中下標為指定index元素 例:lindex key 3
llen key 獲取列表key的長度
lrem key count value 從左至右刪除列表中指定個數與指定value值相等的value 例:lrem k1 1 4 4這個元素被刪除了
ltrim key start stop 刪除指定區域外的元素
rpoplpush source destination 將列表source中的尾元素插入到列表destination中,作為頭元素 例:rpoplpush k1 k2 (將本列表尾元素放另一個列表當頭元素)
lset key index value 將列表key下標為index的元素設為value 例:lset k1 0 222(將0下標下的元素替換成22)
linsert key before|after pivot value 將值插入到指定值之前或之後 例:linsert k1 before 5 100(將k1域內值5前插入100,元素非下標)
集合類型 set(redis的Set時String類型的無序集合,成員唯一,集合中不重覆)
sadd key member member ... 將一個或多個member元素加入集合key中,已存在集合的member元素不加入 例:sadd k1 1 2 3 4
smembers key 獲取聚合key中所有元素
sismember key member 判斷member是否是集合key的成員 例:sismember k1 1
scard key 獲取聚合中元素個數
srem key member 刪除聚合中一個或多個元素(指定刪除某個元素) 例:srem k1 2
srandmemner key [count] 隨機返回集合中一個或多個元素 count 是返回的個數
spop key 隨機刪除集合中的一個元素
smove source destination member 將member元素從一個集合移到另一個集合 例:smove k1 k2 2(將元素2從k1 移到k2)
有序聚合zset(sorted set):跟set差不多,不同的是zset得每個元素都會關聯一個分數(分數可重覆),redis通過分數來為集合中的成員進行排序
zadd key score member 將一個或多個member元素及其score值加入到有序集合 例:zadd k1 100 likaihua 90 likaihua2
zrange key start stop 獲取有序集合key中,指定區間的成員,按score大小排序 例:zrange k1 0 -1
zrevrange key start stop 獲取有序集合key中,指定區間的成員,按score小大排序 例:zrange k1 0 -1
zrem key member 刪除有序集合key中得一個或多個成員 例:zrem k1 likaihua
zcard key 獲取集合個數
zrank key member 獲取有序集合key中,成員member排名,有序集成員按score值從小到大排列 例:zrank k1 likaihua
zrevrank key member 獲取有序集合key中,成員member排名,有序集成員按score值從大到小排列
zrangebyscore key start stop 獲取有序集合key中,所有score值介於min和max之間的成員 例:zrange k1 100 90
zrevrangebyscore key start stop 獲取有序集合key中,所有score值介於max和min之間的成員
zcount key min max 獲取有序集合key中,所有score值介於min和max之間的成員個數 例:zcount k1 10 100
score(分數)
Table鍵 補全命令
官方命令文檔:redisdoc.com
redis的發佈和訂閱
發佈訂閱:redis發佈訂閱(pub/sub)是一種消息通信模式;也稱為生產者模式,實現消息隊列的一種方式
消息隊列三要素:1,生產者(producer)2,消費者(consumer)3,消息服務(broker)
三者關係:1 (producer)——>3 (redis在次充當consumer)——>2(consumer)
一個消息發佈者,多個消息訂閱者
命令實現:1,開啟4個redis客戶端,三個作為消息訂閱者,一個作為消息發佈者:./redis-cli
2,消息訂閱者:subscribe channel
// 如果是訂閱匹配模式:psubscribe chan * 表示匹配以chan開頭的頻道主題都能拿到
3,消息發佈者:publish channel message
//就跟扶貧一樣,國家把錢給政府幹部,幹部(幹部===消息發佈者)發錢,帶有精準扶貧這個標識人就可以憑此去拿錢(貧困戶==消息訂閱者)
jedis編程實現:
訂閱者:
public void onMessage(String channel, String message){ //封裝的回調函數
System.out.println("頻道"+channel+"發佈了消息"+message);
}
public static void main (String [ ] arg){
Jedis jedis = new Jedis ("192.168.0.1" ,6379); //連接redis
Sub sub = new Sub(); //創建訂閱者對象
jedis.subscribe(sub, "channel");
}
發佈者:
public static void main (String [ ] arg){
Jedis jedis = new Jedis ("192.168.0.1" ,6379); //連接redis
jedis.publish("channel", "hello world"); //發佈消息
jedis.close();
}
redis事務(redis中的事務是一組命令集合,至少兩條以上命令,redis事務保證這些命令被執行時不會被其他操作打斷)
正常流程:1,MULTI:該命令告訴redis接下來的命令暫不執行,將其暫存(開啟事務)
2,SADD "user1" 第一天命令進入等待隊列
3,SADD "user2"第二條命令進入等待隊列
4,EXEC 告知redis執行暫存的命令(提交事務) //放棄事務:DISCARD,不執行,事務放棄
//就跟坐客車(事務 == 大客車)一樣,單個不走,包車不准。等人多了,包圓兒了一塊走。
命令示例:
MULTI
set k2(key) v2(value)
set k3(key) v3(value)
EXEC
也存在異常和例外情況:1,語法錯誤,事務回滾不執行
2,語法正常,邏輯錯誤,例如incr給一個字元加1,或者不給值,能夠入隊,但提交事務後會顯示該語句存在錯誤
鎖:
悲觀鎖:當有人讀取數據時會被認為要更改數據,因此每次在讀取數據時會先上鎖,直到這個線程拿到鎖為止。(本線程結束後其他線程才能進來讀取數據。就跟上廁所似的,進去先鎖門,自己拉完了別人才能進來拉)
樂觀鎖:當有人讀取數據時不會被認為更改數據,不上鎖。但在更新時會判斷在此期間是否有人更改數據,一般用版本號機制進行判斷。
悲觀鎖的判斷機制:大多數基於數據版本號機制實現。版本號?:即為數據增加一個版本標識。
一般通過為資料庫表添加“version”欄位來實現讀取數據時,也將此版本一同讀出。之後來讀取數據的人提交數據更新時,會對此版本號加1。
此時提交數據的版本號與資料庫表對應記錄的當前版本號對比,若提交數據版本號大於資料庫表當前版本號,則准予更新(資料庫當前版本號只會更新一次)
示例:
1,A操作員將用戶數據讀取(version=1),進行修改操作。
2,B操作員將用戶數據讀取(version=1),進行修改操作。
3,A完成操作,提交數據時(version +1 =2),提交更新。此時提交數據版本號大於資料庫記錄的當前版本號,准許提交。
4,B完成操作,提交數據時(version +1 =2),提交更新。但是此時的資料庫記錄的版本號已經被A提交數據後更新為2了,所以B提交的版本號不大於資料庫記錄的當前版本號,則不准予提交數據更新。
因為資料庫記錄的版本號只更新一次,誰快先更新了,版本號就變了,必須等上一個線程完成後再進去操作。(就爭媳婦似的的,誰下手快生了娃,誰就穩了)
redis的watch機制實現樂觀鎖(監視一個或多個key,如果在事務exec執行之前這個key被其他命令更改,那麼該事務將會被打斷)
命令如下:
set k1 1 //設k1為1
watch k1 //監視k1
set k1 2 //k1值在被監視時被更改為2,另外人開客戶端更改也一樣
multi //開始事務
set k1 3 //將k1值改為3
exec //提交事務
輸出null,事務被放棄。檢測到k1也被更改為2,不再是1了。
(就像本來你跟你女朋友快要結婚了,但是結婚前一天在你爸媽的眼皮子底下決定跟別人私奔,你爹媽知道了不想讓你背鍋,在你們結婚時強行拆散,唉,真慘。)
redis的持久化機制
持久化概述:持久化==存儲,就一直存著可以。
redis持久化:redis數據存儲在記憶體中,記憶體是瞬時的,如果發生宕機或者系列糟糕情況,記憶體會丟失。redis提供兩者持久化機制
//就跟男人一樣,要持久,持之以恆,堅定不移。
RDB方式:在指定的時間間隔內將記憶體中的數據快照寫入磁碟,數據恢復時將快照文件直接再讀到記憶體
步驟:在redis.conf文件中配置
配置格式:save <seconds><changes>
save 900 1 //900秒內一次數據更改會保存一次
save 3000 10
save 6000 20
配置文件redis.conf中搜索SNAPSHTTING:dbfilename:設置RDB文件名。預設文件名為dump.rdb //就是可以修改保存文件的名字
dir:指定RDB和AOF的文件目錄 //修改保存文件的指定目錄
//修改redis.conf文件後要重啟一下redis
AOF方式:redis每收到一條修改命令時,它將命令寫道一個AOF文件中(不記錄讀命令),當redis重啟時,再通過AOF中的所有命令在恢復
步驟:rdis.conf文件中搜索APPEND ONLY MODE
1,將append only改為yes,預設no;
AOF相關設置: 1,appengfilename:AOF文件名,可改,預設:appendonly.aof
////查看aop文件存儲的命令:1,ll *.aop;2,cat appendonly .aof
2,appendfsync:配置向aof文件寫命令數據策略:
1,append fsync always 每次執行寫入都會執行同步,慢且安全
2,append fsync everysec 每秒執行一次同步操作
3,append fsync no 不主動進行同步操作,交給系統來做,30秒一次,快但不且不安全
3,auto-aof-rewrite-percentage(例如:100):設置當目前aof文件大小超過上一次重寫時aof文件大小的百分之多少時,將再次進行重寫;若之前未進行重寫,則以啟動時最小aof文件大小為依據;
//進行文件優化,例:set k1 1 後再執行 set k1 2,那麼set k1 1則不被記錄,只記錄有用的命令
4,auto-aof-rewtite-min-size(例如:64mb):設置允許重寫的最小aof文件大小
總結:可以同時使用兩種方式,預設優先載入aof
redis集群
主從複製
主從複製(master/slave):
簡介:redis做集群,為保證單點故障,就將數據複製多芬島多台不同伺服器,即使其中一臺出現故障,其他服務仍可運行。
實現:部署多台redis,併在配置文件中指定之間的主從關係。主負責寫,同時將寫入數據實時同步到從機器,即主從複製。master/slave,redis預設master用於寫,slave用於讀。
配置方式一:修改配置文件,啟動時,伺服器讀取配置文件,自動成為指定伺服器的從伺服器,構成主從複製關係。
主伺服器(master)
include /usr/local/redis-5.0.3/redis.conf
daemonize yes
port 6380
pidfile /var/run/redis6380.pid
logtile 6380.log
dbfilename dump6380.rdb
從伺服器(slave)
include /usr/local/redis-5.0.3/redis.conf
daemonize yes
port 6381
pidfile /var/run/redis6380.pid
logtile 6381.log
dbfilename dump6381.rdb
slaveof 127.0.0.1 6380
示例:(由於只有一臺伺服器,因此在一個redis中啟三個實例,一個master兩個slave)方便觀看就開4個客戶端視窗。
以下為客戶端視窗 1。
bin目錄下
cp redis.conf redis6380.conf //複製原來redis6379.conf配置文件,並生成新的redis6380.conf配置文件
ll //出現redis6380.conf文件
>redis6380.conf //滯空redis6380.conf文件
vim redis6380.conf //進入redis6380.conf文件,添加主服務的配置
配置master
include /usr/local/redis-5.0.3/redis.conf
daemonize yes
port 6380
pidfile /var/run/redis6380.pid
logtile 6380.log
dbfilename dump6380.rdb
:wq //如果無法保存退出,就按下esc鍵再,:wq a.txt
配置從slave
cp redis6380.conf redis6381.conf //複製redis6380.conf文件
vim redis6381.conf //進配置文件配置從
include /usr/local/redis-5.0.3/redis.conf
daemonize yes //表示後臺啟動
port 6380
pidfile /var/run/redis6380.pid
logtile 6380.log
dbfilename dump6380.rdb
slaveof 127.0.0.1 6380 //設置是6380的從伺服器
:wq //如果無法保存退出,就按下esc鍵再,:wq a.txt
cp redis6380.conf redis6382.conf //複製redis6380.conf文件
vim redis6381.conf //進配置文件配置從
include /usr/local/redis-5.0.3/redis.conf
daemonize yes
port 6380
pidfile /var/run/redis6380.pid
logtile 6380.log
dbfilename dump6380.rdb
slaveof 127.0.0.1 6380 //設置是6380的從伺服器
:wq //如果無法保存退出,就按下esc鍵再,:wq a.txt
客戶端視窗2
./redis-server ../redis6380.conf //後臺啟動master
./redis-server ../redis6381.conf //後臺啟動slave
./redis-server ../redis6382.conf //後臺啟動slave
ps -ef | grep redis //查看這三個進程是否啟動
如果已經有三個進程的了,也可以檢查各個埠所處角色
./redis -cli -p 6380 //開啟6381客戶端
info replication //插看伺服器角色命令
查看的信息:
role:master(主) //角色master
connected_slaves:2 //兩個從,埠號分別為
slave0:port:6381
slave1:port:6382
客戶端視窗3
./redis -cli -p 6381 //開啟6381客戶端
info replication //插看伺服器角色命令
查看的信息:
role:slave(從) //角色slave
master_host:127.0.0.1 //主是本地的
master_port:6380 //埠號為6380
master_link_status:up //開啟狀態
客戶端視窗4
./redis -cli -p 6382 //開啟6381客戶端
info replication //插看伺服器角色命令
查看信息與3一樣
配置完成可測試
1,回到master所在客戶端視窗
set k1 v1
set k2 v2 //設置兩個值,在從伺服器去取,看是否能讀取值
2,回到任意一個slave所在客戶端視窗
get k1
get k2
3,看能否讀到值,讀到即配置成功
get k3 //讀master為設置的值看是否能讀到
輸出null,未讀到;
4,回到master所在客戶端視窗
set k3 v3 //設置k3,再去slave讀,看是否能讀取
5,回到任意一個slave所在客戶端視窗
get k3
輸出:v3 //讀取成功
主從關係配置完成
如果現在出現問題了,master伺服器宕機了,關閉了,主沒了,只有從了,怎麼辦?
引入新的處理方式
容災處理(冷處理):當master服務出現故障後,需要手動將slave中的一個提升為master,將剩下的slave重新掛至新的master上;
命令如下:
slaveof no one :將一臺slave伺服器提升為master
slaveof 127.0.0.1 6381(新提上slave埠號):將slave掛至新的master上
操作示例:
1,在master所在伺服器客戶端
shutdown //關閉master,模擬master出故障
ps -ef | grep redis //查看redis6380.conf進程是否被關閉
2,在任意一個slave所在伺服器客戶端
slaveof no one //提升為主
info replication //查看所處角色即從服務
顯示信息
role:master //角色為主
connected_slaves:0 //沒有從伺服器
3,在另外slave中的任意一個slave所在伺服器客戶端
slaveof 127.0.0.1 6381 //將本slave掛至新的master上去
info replication //查看角色及主服務
顯示信息
role:slave
master_host:127.0.0.1
master_port:6381 //掛在了新的master上了
4,假如現在原來的master6380伺服器修好
./redis-server ../redis6380.conf //後臺啟動
ps -ef | grep redis //查看進程是否被啟動
./redis-cli -p 6380 //進入redis
info replication //查看角色
顯示信息
role:master //角色為master
connected_slaves:0 //slaves為0
原來master重啟後,預設角色為master現在將它掛至新的6381master上去
slaveof 127.0.0.1 6381 //將本slave掛至新的master上去
總結:
1,使用到的相關命令:
./redis-cli -p 6380 進入指定客戶端埠
info replication 查看redis伺服器所處角色
如果不配置啟動,預設為master
2,master下線,寫請求無法執行;slave下線,讀請求處理性能下降
3,master故障,需要手動提升一個slave為master。其他的slave要重新掛至新的master上去