redis簡介: node
一、Redis是一款開源的,ANSI C語言編寫的,高級鍵值(key-value)緩存和支持永久存儲NoSQL數據庫產品。 二、Redis採用內存(In-Memory)數據集(DataSet)。 三、支持多種數據類型。 四、運行於大多數POSIX系統,如Linux、*BSD、OS X等。 五、做者:Salvatore Sanfilippo
拷貝的簡介,要想看的話,本身百度,不少這裏就不介紹了,直接進入主題。
redis安裝:linux
redis安裝yum:
yum安裝 配置文件在etc下 redis.conf
yum install -y epel-release # 擴展源下載 yum install -y redis #安裝 systemctl enable redis #開機自動啓動 systemctl start pedis #啓動redis
redis安裝源碼包:
下載地址http://download.redis.io/releases/ #下載 yum install -y lrzsz #這個包是上傳工具 tar -zxvf redis-3.2.6.tar.gz #解壓 cd redis-3.2.6 #進入 make # 有可能報錯 redis編譯報致命錯誤:jemalloc/jemalloc.h:沒有那個文件或目錄 解決 make MALLOC=libc cp redis.conf ../redis6380/ #配置文件 cp src/redis-server ../redis6380/ #啓動文件 主程序 ./redis-server ./redis.conf #啓動
配置文件說明redis
egrep -v "^#|^$" redis.conf > redis.conf2 #配置文件去除開頭帶#跟空行 方法有不少 怎麼熟悉怎麼來 mv redis.conf redis.conf_bak #備份原配置文件 mv redis.conf2 redis.conf #覆蓋原配置文件 vim redis.conf #修改端口等信息
bind ip地址 #就在內網上開 protected-mode yes #啓動安全機制 requirepass root #結合安全機制 設置密碼 demonize yes #(配置文件裏面參數 後臺啓動) pidfile /var/run/redis_6380.pid #pid文件 logfile "/data/redis6380/redis.log" #日誌文件 port 6379 #端口 appendonly no -> yes #日誌開關 記錄數據變化的 持久化策略開關 logfile stdout -> ./logs/redis.log #日誌錯誤文件 dbfilename dump.rdb #持久化數據文件。至關於數據庫的數據文件 rdbcompression yes #壓縮 這些都是經常使用的配置,有些配置能夠在redis內部用命令來設置
/usr/lib/systemd/system/redis.ervice (yum 安裝的有 源碼包安裝沒有)
簡單的多實例數據庫
複製這個目錄 修改端口 就是多實例 drwxr-xr-x 2 root root 96 7月 19 22:27 redis6380 drwxr-xr-x 2 root root 96 7月 19 22:31 redis6381
分別在這兩個目錄啓動 tcp 0 0 127.0.0.1:6380 0.0.0.0:* LISTEN 13202/./redis-serve tcp 0 0 127.0.0.1:6381 0.0.0.0:* LISTEN 13228/./redis-serve
redis保護機制vim
修改完配置文件redis.conf protected-mode yes #啓動安全機制 requirepass root #結合安全機制 設置密碼
例子: 127.0.0.1:6380> get foo #須要認證 (error) NOAUTH Authentication required 127.0.0.1:6380> auth root #我來認證 OK 127.0.0.1:6380> get foo #成功 "guohongze"
持久化|策略緩存
RDB 持久話能夠在指定時間間隔內生成數據集的時間點快照(point-in-time-snapshot) AOF 持久化記錄服務器執行的全部寫操做的命令,並服務器啓動時,經過從新執行這些命令來還原數據集。 save 900 1 save 300 10 save 60 10000 900秒(15分鐘) 有一次操做的話 就保存一次 300秒(5分鐘) 有十次操做的話 就保存一次 60秒(1分鐘) 有10000次操做的話 就保存一次
同步安全
配置文件redis.conf appendfsync everysec no 表示等操做系統進行數據緩存同步到磁盤上linux約30秒 always 即是每次更新操做後調用fsunc()將數據寫到磁盤 (慢 安全) everysec 表示每秒同步一次 (折中,默認值) 後期 優化能夠考慮調整這些參數
redis高級應用 隊列 | 訂閱ruby
發佈消息一般有兩種模式:(隊列模式queuing 和發佈-訂閱模式publish-subscribe) 隊列模式: consumers(消費者)能夠同時從服務器端讀取消息,每一個消息只被其中一個consumer(消費者)讀到。 發佈-訂閱模式: 中消息被廣播到全部consumer(消費者)中,topic中的消息將被分發到組中的一個成員中。 同一組中的consumer能夠在不一樣的程序中,也能夠在不一樣的機器上。 隊列模式例子: 127.0.0.1:6380> lrange bao 0 10 1) "bao6" 2) "bao5" 3) "bao4" 4) "bao3" 5) "bao2" 6) "bao1" 7) "bao" 127.0.0.1:6380> rpop bao #刪除一個 "bao" 127.0.0.1:6380> rpop bao "bao1" 127.0.0.1:6380> rpop bao "bao2" 127.0.0.1:6380> lrange bao 0 10 #查看 1) "bao6" 2) "bao5" 3) "bao4" 4) "bao3" 127.0.0.1:6380> lpush bao bao7 #添加 (integer) 5 127.0.0.1:6380> lpush bao bao8 (integer) 6 127.0.0.1:6380> lpush bao bao9 (integer) 7 127.0.0.1:6380> lrange bao 0 10 1) "bao9" 2) "bao8" 3) "bao7" 4) "bao6" 5) "bao5" 6) "bao4" 7) "bao3" 先進先出 發佈訂閱模式: 發佈訂閱(pub/sub)是一種消息通信模式:發送者(pud)發送消息,訂閱者(sub)接收消息 redis 客戶端能夠訂閱任意數量的頻道 兩臺client端同時訂閱 client1命令:subscribe wanghong #訂閱網紅 關注一個頻道 網紅頻道 127.0.0.1:6380> SUBSCRIBE mq1 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "mq1" 3) (integer) 1 1) "message" 2) "mq1" 3) "qing guan zhu wo " #這條消息是redis服務器端發佈以後出現的 client2命令:subscribe wanghong 被訂閱端發佈一個消息 server命令:publish mq1 「qing guangzhu wo」 127.0.0.1:6380> publish mq1 "qing guan zhu wo " (integer) 2
redis事物bash
Redis 事務能夠一次執行多個命令 事務是一個單獨的隔離操做:事務中的全部命令都會序列化、按順地執行。 事務在執行的過程當中,不會被其餘客戶端發送來的命令請求所打斷。 原子性:事務命令要麼所有被執行,要麼就所有都不執行 執行過程 開始事務 命令入隊 執行事務 127.0.0.1:6380> ZADD salary 3000 guohongze 5000 oldboy 建立一個zadd的有序 集合 (integer) 2 127.0.0.1:6380> multi #標記一個事務塊的開始 OK 127.0.0.1:6380> zincrby salary 1000 guohongze #添加事務一 guohongze加1000 QUEUED 127.0.0.1:6380> zincrby salary -1000 oldboy #添加事務二 oldboy減1000 QUEUED 127.0.0.1:6380> exec #執行全部事務塊內的命令 1) "4000" 2) "4000" 127.0.0.1:6380> ZRANGE salary 0 -1 withscores #看一下有序集合的數據 1) "guohongze" 2) "4000" 3) "oldboy" 4) "4000" ####保證數據的一致性
redis慢日誌查詢服務器
Slowlog 是redis用來記錄查詢執行時間的日誌系統 Slowlog 保存在內存裏面,讀寫速度很是快 能夠經過改寫redis.conf文件 後者 config get 和config set命令對他們動態地修改 slowlog-log-slower-than 10000 #超過多少微秒 #配置文件設置 config set slowlog-log-slower-then 100 #裏面設置 config set slowly-max-len 1000 #保存多少條慢日誌 Config get slow* #查詢 Slowly get Slowly reset
redis數據備份
config get dir 獲取當前目錄 Save 備份(無持久化策略時),生成時在redis當前目錄中。 恢復時只需將dump.db放入redis當前目錄 (放入時候須要redis未啓動,備份文件有數據或者在當前目錄下,方可啓動redis主程序) 當配置文件持久化關閉時(appendonly no)redis須要手動保存 直接save 就是產生dump.rdb 文件
redis複製(Replication)
config get dir 獲取當前目錄 Save 備份(無持久化策略時),生成時在redis當前目錄中。 恢復時只需將dump.db放入redis當前目錄 (放入時候須要redis未啓動,備份文件有數據或者在當前目錄下,方可啓動redis主程序) 當配置文件持久化關閉時(appendonly no)redis須要手動保存 直接save 就是產生dump.rdb 文件 ------------redis複製(Replication)----------- 在從服務器刪除舊版本數據集並載入新版本的數據集的那段時間內,連接請求會被阻塞 能夠經過複製功能來讓主服務器免於執行持久化操做,只要關閉主服務器的持久化功能,而後由從服務器去執行持久化操做便可。 避免一個問題: 1.假設節點A爲主服務器,而且關閉了持久化,而且節點B和節點C從節點A複製 2.節點A崩潰,而後由自動拉起服務重啓了節點A,因爲節點A的持久化被關閉,因此重啓以後沒有任何數據 3.節點B和節點C將從節點A複製數據,可是A節點的數據是空的,因而就把自身保存的數據副本刪除了 解決辦法:沒有自動拉起服務就行了 ------注意 積壓空間問題---: 初次連接仍是從新連接,當創建一個從服務器時,從服務器都將向主服務器發送一個sync命令。 接到sync命令的主服務器將開始bgsave,並在保存操做執行期間,將全部新執行的寫入命令都報錯到一個緩衝區裏面。 當gbsave執行完畢後,主服務將執行保存操做所得的.rdb 文件發送給從服務器,從服務器接受這個.rdb文件,並將文件中的 數據載入到內存中 --------配置-------: 1。只須要在配置文件中增長一行: slaveof 192.168.1.1 6379 其中 92.168.1.1 和 6379 替換成你的主服務器的ip和端口 壞處:崩潰了 不敢重啓 2.調用命令 slaveof 192.168.1.1 6379 便可 其中 92.168.1.1 和 6379 替換成你的主服務器的ip和端口 好處 你要重啓了 手動命令 slaveof no one 將從變成主 ------手工主從切塊------- 在原來的主上面關閉redis 在第一個從上面 slaveof no one 在第二臺從 上面 添加 slaveof 192.168.1.1 6379 第一臺從服務器的ip和端口 若是第一臺開啓了 那就成了從服務器了
redis sentinel(哨兵)
sentinel是redis官方推薦的高可用(HA)解決方案 1。監控(monitoring)Sentinel不斷地檢查你的主服務器和從服務器是否運做正常 2.提醒(notification)當被監控的某個redis服務器出現問題時,Sentinel可經過API向管理員或者其餘應用程序發送通知。 3.自動故障遷移(Automatic failover):當一個主服務器不能正常工做時候,Sentinel會開始一次自動故障遷移操做,他會將失效主服務器的器中一個從服務升級爲新的主服務器,並讓失效的主服務器的其餘從服務器改成複製新的主服務器;當客戶端試圖連接失效的主服務器時,集羣也會向客戶端返回新主服務器的地址,使得集羣可使用新主服務器代替失效服務器 mkdir S1 #建立一個目錄 cp redis-3.2.6/sentinel.conf /data/S1/ #配置文件 cp redis-3.2.6/src/redis-sentinel /data/S1/ #主程序文件 sentinel 端口26379 -------------sentinel.conf配置文件---- sentinel monitor mymaster 127.0.0.1 6381 1 #有兩個sentinel 最後的是2集羣參數 sentinel auth-pass mymaster luyx30 #安全信息 sentinel down-after-milliseconds mymaster 10000 #1萬毫秒 當主從切換多久後認爲主從切換失敗 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 180000 啓動 ./redis-sentinel ./sentinel.conf 修改端口號 還有sentinel monitor mymaster 127.0.0.1 6381 2 最後一個參數修改爲2
redis集羣
Redis集羣時一個能夠在多個redis節點之間進行數據共享的設施(installation) Redis集羣不支持那些須要同時處理多個鍵的redis命令,由於執行這些命令須要在多個redis節點之間移動數據,而且在高負載的狀況下,這些命令將下降redis羣集的性能,並致使不可預測的行爲 Redis集羣經過分區(partition)來提供必定程度的可用性(rvailability):即便集羣中有一個部分節點失效後者沒法進行通訊,集羣也能夠繼續處理命令請求 將數據自動切分(split)到多個節點的能力 當集羣中的一部分節點失效或者沒法進行通訊時,仍然能夠繼續處理命令請求的能力 安裝集羣 16383個哈希槽 Yum install ruby rubygems -y gem install redis 若是卡住了使用國內鏡像 gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org gem sources -l 配置文件redis.conf port 7000 #端口 cluster-enabled yes # cluster-node-timeout 5000 appendonly yes pidfile "/var/run/redis.pid" dir "./" 複製六個實例 for no in 0 1 2 3 4 5;do cp -r redis6380/ 700$no;done #複製實例 修改配置文件(這裏有一個腳本) #!/bin/bash rm -rf /data/700* for no in 0 1 2 3 4 5;do cp -r redis6380/ 700$no;done for no in 0 1 2 3 4 5;do rm -rf /data/700$no/dump.rdb;done for no in 0 1 2 3 4 5 do cd /data/700$no sed -i "s/port 6380/port 7000/g" redis.conf echo "cluster-enabled yes" >> redis.conf echo "cluster-config-file nodes.conf" >> redis.conf echo "cluster-node-timeout 5000" >> redis.conf sed -i "s/appendonly no/appendonly yes/g" redis.conf sed -i "s/redis_6380.pid/redis_700$no.pid/g" redis.conf sed -i "s/^dir/d" redis.conf echo 'dir "./"' >>Reds.conf done for no in 0 1 2 3 4 5;do cd /data/700$no && ./redis-server ./redis.conf;done #啓動 建立集羣的命令: /data/redis-3.2.6/src/redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 #--replicas 1 #幾個從服務器 當前是一個 1.給定redis-trib.rb 程序的命令是create 這個表示咱們但願建立一個新的集羣 2.選項 --replicas 1 表示咱們但願爲集羣中的每一個主節點建立一個從節點 3.以後跟着的其餘參數 則是實例的地址列表,咱們但願程序使用這些地址所指示的實例來建立新集羣 登錄集羣 redis-cli -c -p 7000 # 必須加c 不加c參數登錄進去是有問題的 不加c是單機 集羣狀態 redis-cli -p 7000 cluster nodes |grep master 故障轉移 redis-cli -p 7002 debug segfault 查看狀態 redis-cli -p 7000 cluster nodes |grep master 從新分片 redis-trib.rb reshard 127.0.0.1:7000
命令
Redis-cli -p 6379 #進入(yum安裝/usr/bin/redis ) 127.0.0.1:6380> set foo guohongze #建立一個鍵值對 127.0.0.1:6380> get foo #取出foo 對應的 值 127.0.0.1:6380> keys * #獲取全部的key [root@localhost redis6380]# /data/redis-3.2.6/src/redis-cli -p 6380 #進入(源碼安裝) 127.0.0.1:6380> SHUTDOWN #中止服務 not connected> exit #退出
127.0.0.1:6380> auth root #我來認證 一種保護數據機制
關於redis配置命令
Info 服務器信息 client list 查看有一個客戶端 client kill IP:port config get * config resetstat 重置統計 config get/set 動態修改 Dbsize flushall 清空全部數據 select 1 flushDB 清空當前庫 Monitor 監控實時指令 最爲經常使用 shutdown 關閉服務器 Save 將當前數據保存 slaveof host port 主從配置 slaveof no ond Sync 主從同步 Role 返回主從角色
redis一些簡單的練習
------------------------字符串------------------------- ------set|get|type--- 127.0.0.1:6380> set name goujongze #建立一個name的鍵值對 OK 127.0.0.1:6380> get name #get name "goujongze" 127.0.0.1:6380> type name #查看類型 string 127.0.0.1:6380> 一個key 對應的值 最大能儲存512MB ----append----- 127.0.0.1:6380> APPEND name 123 # 在值的尾部多加一個值 (integer) 12 127.0.0.1:6380> get name "goujongze123" ----Mset------- 127.0.0.1:6380> MSET name guohongze foo oldboy #同時設置一個或者多個鍵值對 OK 127.0.0.1:6380> MGET name foo 1) "guohongze" 2) "oldboy" 127.0.0.1:6380> ----strlen------- 127.0.0.1:6380> strlen name #字符串長度 (integer) 9 127.0.0.1:6380> get name "guohongze" 127.0.0.1:6380> ----incr|decr|incrby|decrby------- 127.0.0.1:6380> set age 33 OK 127.0.0.1:6380> 127.0.0.1:6380> INCR age #incr 加一 decr 減一 (integer) 34 127.0.0.1:6380> INCR age (integer) 35 127.0.0.1:6380> decr aghe (integer) -1 127.0.0.1:6380> decr aghe (integer) -2 127.0.0.1:6380> incrby age 100 #incrby|decrby 加一百 減一百 (integer) 137 127.0.0.1:6380> DECRBY age 100 (integer) 37 ----EXISTS------- 127.0.0.1:6380> EXISTS name #檢查name是否存在 1 是存在 0 不存在 (integer) 1 127.0.0.1:6380> EXISTS asdasd (integer) 0 127.0.0.1:6380> ------------------------hash(哈希)------------------------- Redis hash 是一個鍵值對集合 Redis hash是一個string類型的field和value的映射表 Hash特別適合用於儲存一個對象 每一個hash能夠儲存 2^32-1 鍵值對 ----------hset| hgetall|hget| hget---------- 127.0.0.1:6380> hset user:1 name gouhongze #設置一個user:1對象 (integer) 1 127.0.0.1:6380> type user:1 hash 127.0.0.1:6380> hset user:1 age 35 (integer) 1 127.0.0.1:6380> hset user:1 sex male (integer) 1 127.0.0.1:6380> hgetall user:1 #get user:1 這個對象全部值 1) "name" 2) "gouhongze" 3) "age" 4) "35" 5) "sex" 6) "male" 127.0.0.1:6380> hget user:1 age #get 一個age 值 "35" 127.0.0.1:6380> hget user:1 name #get 一個name 值 "gouhongze" 127.0.0.1:6380> hmget user:1 name age #get 兩個值 1) "gouhongze" 2) "35" --——————————---del---——————————————————--- 127.0.0.1:6380> keys * 1) "user:1" 2) "foo" 3) "name" 4) "aghe" 5) "oldboy" 6) "age" 127.0.0.1:6380> del oldboy #刪除一個 (integer) 1 127.0.0.1:6380> keys * 1) "user:1" 2) "foo" 3) "name" 4) "aghe" 5) "age" --------------hdel-------————————————-- 127.0.0.1:6380> hdel user:1 age. #刪除user:1 裏面的age (integer) 1 127.0.0.1:6380> hgetall user:1 1) "name" 2) "xiaoqi" 3) "sex" 4) "male" ------------------------list(列表)------------------------- Redis列表是簡單的字符串列表 按照插入順序排序每一個 List能夠存儲2^32-1 鍵值隊 -------lpush|lrange----- 127.0.0.1:6380> LPUSH list1 bmw benz toyota honda #建立一個list1 (integer) 4 127.0.0.1:6380> type list1 #查看類型 list 127.0.0.1:6380> LRANGE list1 0 10 #便利一個列表 0是開始位 10結束位 1) "honda" 2) "toyota" 3) "benz" 4) "bmw" 127.0.0.1:6380> lpush list1 volvo #前面插入數據 (integer) 5 127.0.0.1:6380> rpush list1 byd #後面插入數據 (integer) 6 127.0.0.1:6380> lrange list1 0 10 #遍歷一個list 1) "volvo" 2) "honda" 3) "toyota" 4) "benz" 5) "bmw" 6) "byd" -------rpop|lpop------- 127.0.0.1:6380> lrange list1 0 10 1) "volvo" 2) "honda" 3) "toyota" 4) "benz" 5) "bmw" 6) "byd" 127.0.0.1:6380> rpop list1 #最後的一個刪除 "byd" 127.0.0.1:6380> lpop list1 #最前的一個刪除 "volvo" 127.0.0.1:6380> LRANGE list1 0 10 1) "honda" 2) "toyota" 3) "benz" 4) "bmw" ----llen---- 127.0.0.1:6380> llen list1 #list長度 (integer) 4 127.0.0.1:6380> lrange list1 0 10 1) "honda" 2) "toyota" 3) "benz" 4) "bmw" -----------lrem-------- 127.0.0.1:6380> lrange list1 0 10 1) "bao8" 2) "bao7" 3) "bao6" 4) "bao6" 5) "bao5" 6) "bao4" 7) "bao3" 8) "bao2" 127.0.0.1:6380> lrem list1 1 bao6 #1數量 刪除bao6 (integer) 1 127.0.0.1:6380> lrange list1 0 10 1) "bao8" 2) "bao7" 3) "bao6" 4) "bao5" 5) "bao4" 6) "bao3" 7) "bao2" ------lset------ 127.0.0.1:6380> lset list1 0 baozi001 修改list裏面索引爲0的元素 OK 127.0.0.1:6380> lrange list1 0 10 1) "baozi001" 2) "bao7" 3) "bao6" 4) "bao5" 5) "bao4" 6) "bao3" 7) "bao2" ------lindex------ 127.0.0.1:6380> lindex list1 0 "baozi001" --------linsert----- 127.0.0.1:6380> LINSERT list1 after bao5 bao6 #在baozi5後面插入baozi6 (integer) 8 127.0.0.1:6380> lrange list1 0 10 1) "baozi001" 2) "bao7" 3) "bao6" 4) "bao5" 5) "bao6" 6) "bao4" 7) "bao3" 8) "bao2"