Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它可以用作數據庫、緩存和消息中間件。 它支持多種類型的數據結構,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與范圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 Redis 內置了 復制(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不同級別的 磁盤持久化(persistence), 并通過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。
CAP理論:任何分布式的存儲系統最多只能滿足以下三種特性中的兩種特性。
C:多個數據節點上的數據一致;(例如mysql數據庫的主從案例:當主服務器開始存儲數據,從服務器同步數據,其時間上會存在一定的時間窗口,此時有兩個客戶端去訪問兩個節點上的數據是,看到的數據可能會有不一致性的結果)
A:用戶發出請求后的有限時間范圍內返回結果;(如果后臺是分布式的數據庫的分布結構,當客戶端去訪問某一個節點時,此節點沒有你所需要的數據,此節點就會去其他節點上的數據庫中查找,中間可能會存在某種問題導致時間的延遲,不能在有限的時間里返回客戶端所需要的數據結果)
P:network partition,網絡發生分區后,服務是否依然可用;(分區容錯性:集群中是通過內網 電纜來連接的,如果中間某個節點斷開了,會造成集群的各個節點無法連接,也無法去決定集群中到底有那部分節點去給客戶端提供數據的服務)由于此特性是集群中必備的特性。
AP理論:一個分布式系統不可能同時滿足C、A、P三個特性,最多可同時滿足其中兩者;對于分布式系統滿足分區容錯性幾乎是必須的。
AP:弱一致性(對數據的一致性可以考慮)常用選擇的結構。
CP:可用性? (對數據的不可用性)
BASE:BA,S,E,基于CAP演化而來(滿足了三種條件,在一定時間,保證數據的可用性)
BA:Basically Available,基本可用;
S:Soft state,軟狀態/柔性事務,即狀態可以在一個時間窗口內是不同步的;
E:Eventually consistency,最終一致性;
redis的特性:
redis是一種非關系型數據庫,redis可以作為分布式存儲,本質上來講,redis是基于內存來工作的,可作為數據庫,緩存,消息隊列。是單進程,持久化(一定時間后會將數據快照到磁盤里去)
程序環境:
配置文件:/etc/redis.conf
主程序:/usr/bin/redis-server
端口號:6379/tcp
客戶端:/usr/bin/redis-cli
Unit File:/usr/lib/systemd/system/redis.service
數據目錄:/var/lib/redis
yum install redis
redis-cli ? (登陸數據庫。開始時密碼沒設默認為空)
redis數據庫,下默認只有0-15號數據庫,其名稱不想MySQL可以隨便命名的,只是編號.例如0號庫,2號庫,修改配置文件可以增加庫的數量。
redis-cli +選項
-a ? (數據庫的密碼)
-p (數據庫的端口號)
-h? (數據庫的所在的服務器的地址,不寫默認為本機)
-n (所要登陸到的哪個數據庫;不寫的話默認為0號庫)
redis數據結構 – 簡介
redis是一種高級的key:value存儲系統,其中value支持五種數據類型:
1.字符串(strings)
help @strings (查看詳細的命令信息)
SET ? (設置字串的鍵值數據:set class m30鍵是class,值是m30)
GET ? (獲取鍵的數據:get class? class是鍵)
EXISTS? (判定指定鍵是否存在:exists class如果存在顯示(integer) 1如果不存在:(integer) 0)
INCR ? (增加鍵值)
DECR ? (減去鍵值)
SETNX ? (如果鍵存在就不設定其值并報錯,如果不存在則設定新的鍵值)
(此前此鍵已經設定了,所以使用setnx在設定此鍵就會失敗,如果需要更改此前設定的鍵值直接使用set class m32重新設定就可以了)
SETEX ? (給一個鍵設置過期時間:setex student 10 wang? 默認為秒;十秒鐘后此鍵值就沒有了)
INCRBYFLOAT
MGET ? (一次獲取多個鍵的值)
MSET ?? (一次設定多個鍵的值)
2? LSET.字符串列表(lists)
help@list ? (查看此類型下的命令選項)
隊列:
LPUSH? (左進)
RPUSH? (右進)
LPOP? (左出)
RPOP? (右出)
LPUSHX
RPUSHX
LRANGE ? (取出指定范圍內的元素)
LINDEX (獲取指定索引的值)
LREM? (移除指定元素)
LTRIM ?? ( 只保留指定范圍內的元素,其他的元素都刪除)
示例1:
rpush weekdays sun? (在weekdays鍵上從右側壓入一個元素sun)
lpop weekdays (從左側取出weekdays鍵的值,此時weekdays鍵里就沒有值了)
示例2:
lpush weekdays mon tou wen? (從左側壓入三個數據;先押入mon;在壓入tou;此時將mon向右擠到第一)
lindex weekdays 0 (查看第一個數據:是wen;第二個數據:tou;第三個數據:mon)
(壓入之后的隊列:wen;ton;mon;所以讀取的順序wen;tou;mon)
rpop weekdays (此時如果從右側彈出一個數據應該是mon)
llen weekdays? (獲取此鍵里元素的個數)
lrange weekdays 0 2? (查看0-2 所對應的元素)
ltrim weekdays 0 1? (只留0號和1號元素,其他的元素都移除)
示例3:
rpush weekdays mon tou wen? (從右側壓入三個數據)
lindex weekdays 0 (查看第一個數據:是mon;第二個數據:tou;第三個數據:wen)
(壓入之后的隊列:mon;tou;wen所以讀取的順序 mon;tou;wen)
rpop weekdays (此時如果從右側彈出一個數據應該是wen)
3.字符串集合(sets)
help @set? (查看詳細的命令)
SADD ? (創建一個集合)
SPOP
SREM? (從指定鍵中移除某個元素)
SRANDMEMBER
SINTER ? (求交集的)
SUNION ?? (求并集的)
示例:
sadd stus tom jeery lili hehe? (創建一個新的集合)
spop stus (從集合中彈出一個元素,不寫個數默認彈出一個。彈出的是隨機的)
srem stus lili ? (刪除集合中,指定的某一個元素)
scard stus? (查看集合當中元素的個數)
smembers stus (查看集合中具體的元素)
sinter stus stus2 ? (對兩個集合做交集運算)
sunion stus stus2? (對兩個集合做并集運算)
sdiff stus stus2 ? (求兩個集合的差集: sdiff stus2 stus:這樣兩種的差集是不一樣的)
(差集的意思是:stus 和stus2取差集,就是先取他么兩個的交集,然后stus集合去掉他們兩個的交集,剩余的元素;stus 2和stus取差集,就是先取他么兩個的交集,然后stus2集合去掉他們兩個的交集,剩余的元素)
4.有序字符串集合(sorted sets)對集合中的元素加上評分。
help @sorted_set (查看詳細的命令和信息)
ZADD
ZCARD
ZCOUNT
ZRANK
示例:
zadd z1 100 tom 33 jerry 88 abab 77 hehe? (添加4個元素及對應的值)
zcard z1? (查看元素的個數)
zrank z1 tom ? (查看tom 所對應的節點,已經排好序了,最大的值其元素節點號越大;所以節點為0的元素應該是Jerry,因為他的值最?。?/p>
zrange z1 0 2? (取出0-2號節點的元素)
zrangebyscore z1 60 100 (取出得分在60-100之間的元素)
5.哈希(hashes)
@hash
HSET ? (設定多個鍵值對)
HMSET
HGET ? (一次獲取一個鍵值)
HMGET (一次獲取多個鍵值)
HKEYS ?? (獲取所有鍵)
HVALS ? (獲取鍵里的所有值)
HDEL ? (刪除某個字段)
HGETALL? (一次獲取所有的鍵和值)
示例:
hmset stu id 1 name tom age 13 (創建一個stu鍵,里面包含三個鍵值對)
hkeys stu (獲取此主鍵stu里的所有鍵的列表:id ;name;age;)
hvals stu ? (獲取此鍵里的所有值:1;tom;13;)
hset stu age 11? (改變某一個鍵的值)
hstrlen stu name (獲取name鍵里元素值的字符長度)
hget stu name? (獲取name鍵里的值)
hdel stu age (刪除age鍵和其對應的值)
hgetall stu (一次獲取此主鍵里的所有鍵和值)
而關于key,有幾個點要提醒大家:
1.key不要太長,盡量不要超過1024字節,這不僅消耗內存,而且會降低查找的效率;
2.key也不要太短,太短的話,key的可讀性會降低;
3.在一個項目中,key最好使用統一的命名模式,例如user:10000:passwd。
auth lv (輸入密碼)
redis 的參數配置和命令詳解:
redis-cli -a lv (輸入密碼進入數據庫)
127.0.0.1:6379> ping ?? (發出ping,會會回應pong已檢測服務器的狀態是否健康)
PONG
auth lv? (可以先連接到數據庫,然后進去再單獨認證)
select 2? (用來切換數據庫的默認是0號數據庫)
keys * (可以顯示當前數據庫所有存在的鍵)
quit? (退出客戶端)
flushdb ? (清空當前數據庫的內容)
flushall? (清空所有庫中的所有鍵數據)
client list (列出所有客戶端的連接信息)
client setname? (設定客戶端連接的名稱)
client getname? (獲取連接的名稱)
client kill ? (斷開哪個連接本機的客戶端)
shutdown ? (關閉服務器)
config get ? (獲取本機的配置參數:config get requirepass:獲取本機的密碼 config get maxclients:獲取本機的最大并發連接數)
config set ? (設定本機的配置參數 config set maxclients 10002:設定本機最大的并發連接數。及時生效,不需要重啟服務)
config rewrite? (將剛才在命令行修改的配置參數,保存到配置文件里,將原有的配置參數覆蓋掉)
info? (查看redis的內部狀態信息)
info cpu ? (只看某一段的信息;如只看cpu的)
如何配置何使用redis
1 .通用配置:
############ GENERAL ################? (通用配置)
daemonize no (是否運行為守護進程;使用systemctl開啟進程,設為no,如果是腳本開啟,此項要開啟)
databases 16 (設定默認庫的個數;databases -1 就代表數據庫的個數不受限制,)
############ SNAPSHOTTING ############## (基于快照做持久化,默認啟用的)
dbfilename “dump.rdb” 默認設置快照的文件名
dir “/var/lib/redis” ? (快照文件存放的路徑;實際工作中需要更改到內村較大的磁盤位置;并且將指定的目錄的屬主和數組都設定為redis所有)
rdbchecksum yes? (每次保存是否要啟用校驗碼校驗,默認為啟用的,也應該是啟用的)
rdbcompression yes ? (快照完是否要壓縮存放,默認是yes,也應該是啟用的)
stop-writes-on-bgsave-error yes (當保存快照時出現錯誤是否要停止redis的寫操作)
關于何使做一次快照定義的規則:(可以自定義規則)
save 900 1 ? (在900s內數據發生了以此修改就做一次快照;如果還沒有一次修改就不需要做快照了)
save 300 10 (在300s內數據發生了十次的修改就做一次快照;如果此條件還沒滿足則執行上面的條件)
save 60 10000? (在60s內數據發生了一萬次修改就做一次快照;如果沒滿足此條件則執行上面的條件)
########### APPEND ONLY MODE #################(基于AOM做持久化的默認不啟用)
appendonly no? (默認關閉此種持久化的方法;若要啟用更改此項配置就可以了)
appendfilename “appendonly.aof” ? (默認生成文件的文件名;文件存放的路徑默認為和快照文件放在一起的,也可以自己指定路徑去存放)
auto-aof-rewrite-percentage 100? (變化的文件和總文件相比超出50%就觸發一次重寫操作)
auto-aof-rewrite-min-size 64mb? (當文件的最小大小為64M;上下兩個條件要同時滿足)
appendfsync everysec(當有鍵發生變化1s內執行記錄操作)
############## NETWORK ################(網絡方面的)
protected-mode yes ? (保護模式 ,默認下無論監聽什么地址都只能通過172.0.0.1來連接)
timeout 0 ? (客戶端連接上,多久不操作就斷開連接,=0代表永久不超時,不斷開連接;當連接連接量較大時,應該設定一個值,來防止那些連接上又不操作的客戶端,以保證其他連接能正常不會阻塞)
tcp-keepalive 300 ? (tcp的連接超時時常)
?
?############ SECURITY ################ (安全方面的)
requirepass “lv” ? (啟用并設置密碼)481行
rename-command flush set ? (將命令重命名;但在主從復制下不推薦使用因為,從服務器無法識別主服務器上的別名命令,就可能無法實現數據的同步操作)
############## LIMITS ###############(資源限制相關的)
maxclients 10000? (最大并發連接數量)
maxmemory ? ? ? (當前內存上指定拿出多少來當redis的內存存儲來用,單位是字節;如果不設置此項,默認會將本機所以的內存來當存儲,直至本機的內存沾滿;一旦本機的內存耗盡,內核會自動殺死最耗內存的進程,所以此項應該設定)
MAXMEMORY POLICY(內存淘汰策略;當redis的內存達到上限,采用什么淘汰機制)
maxmemory-policy noeviction(默認使用的是此機制)
volatile-lru;淘汰那些設定過期時間基于lru算法(最近最少使用的)
allkeys-lru :淘汰所有的鍵基于lru算法 (當緩存使用時不要采用此算法)
volatile-random:僅對設置了過期時間的做隨機淘汰
allkeys-random :所有鍵隨機淘汰
volatile-ttl:對設置過期時間進行逆序淘汰,主要看誰的過期剩余時間
noeviction :不淘汰任何鍵,只是再內存占滿時,發出報錯
maxmemory-samples 5 (每次將五個鍵做對比來淘汰;如果將全部鍵都拿來作比較,來選擇淘汰誰,太浪費資源了,所以每次取5個鍵來做比較,也可自己設置;5個已經足夠接近真實了;10個最真實;3個最快)
?
############# SLOW LOG ##################(慢查詢日志)
slowlog-log-slower-than 10000 (一個鍵的執行時常超過0.01秒就認為是慢的;單位是微秒)
########## ADVANCED CONFIG ##############(高級配置)
hash-max-ziplist-entries 512 (設定最多有多少個鍵值對)
hash-max-ziplist-value 64 (每一個鍵和值的字節最大不能超過64個字節)
client-output-buffer-limit normal 0 0 0(正??蛻舳耍痪彌_池的大小。既接收數據的大?。?br />client-output-buffer-limit slave 256mb 64mb 60(從服務器客戶端;256mb 64mb 60從服務器可以超過64M最大不能超過256M,且時間在60秒內;256硬限制:不可超過的;64為軟限制可以超過但有時間限制,限制為60秒)
client-output-buffer-limit pubsub 32mb 8mb 60 (發布訂閱隊列的客戶端)
緩沖數據:就是接收和發送數據,在對反未接收之前的在本地的緩沖。
Redis的持久化:
1 .? RDB:snapshotting, 二進制格式;按事先定制的策略,周期性地將數據從內存同步至磁盤;數據文件默認為dump.rdb;(缺點:在做快照的那一秒做的操作就會丟失)
客戶端顯式使用SAVE或BGSAVE命令來手動啟動快照保存機制;
SAVE;手動去觸發快照。即在主線程中保存快照,此時會阻塞所有客戶端請求;
BGSAVE:手動去觸發快照;在后臺啟動一個線程去執行快照操作,前臺的客戶請求正常進行
2 .? AOF:Append Only File, fsync
記錄每次寫操作至指定的文件尾部實現的持久化;當redis重啟時,可通過重新執行文件中的命令在內存中重建出數據庫;(將redis的每一條命令都記錄下來,然后通過重放來恢復數據,和MySQL的二進制日志相同;這種方式相較于快照的方式效率低,但不會丟失數據)
BGREWRITEAOF:AOF文件重寫;手動觸發的方式
不會讀取正在使用AOF文件,而是通過將內存中的數據以命令保存至臨時文件中,完成之后替換原來的AOF文件
兩個方式之采取一種就可以了,系統默認是使用做快照的方式來將數據做持久化寫入磁盤里去。
實驗:實現redis的主從配置
1 . 主機器上:
yum install redis
編輯配置文件:
vim /etc/redis.conf
bind 0.0.0.0? (更改此項)
requirepass lv (添加此行設置密碼)481行
ss -nult (查看端口號是否開啟)6379
2 .從節點上的配置:
note01:
yum install redis
編輯配置文件:
vim /etc/redis.conf
bind 0.0.0.0 (更改此項)
slaveof 192.168.60.20 6379 (添加此行設定主節點的IP地址和端口)266行
masterauth lv (指定主節點的密碼)274行
requirepass lv (添加此行設置密碼)482行
systemctl start redis (啟動服務)
ss -nult? (查看端口號是否開啟)6379
note02:
yum install redis
編輯配置文件:
vim /etc/redis.conf
bind 0.0.0.0 (更改此項)
slaveof 192.168.60.20 6379 (添加此行設定主節點的IP地址和端口)266行
masterauth lv (指定主節點的密碼)274行
requirepass lv (添加此行設置密碼)482行
systemctl start redis (啟動服務)
ss -nult (查看端口號是否開啟)6379
最后在主節點上進入到進入到數據庫中:
redis-cli? (進入數據庫)
AUTH lv? (輸入驗證密碼)
CLIENT LIST ? (列出所有的服務器會發現有從客戶端)
INFO replication ? (此命令也可以查看主從節點的詳細信息)
測試:
在主機點上創建一個鍵
redis-cli -a lv(在主節點登陸)
SET CLASS M30
redis-cli -a lv? (在從節點登陸)
KEYS * ? (查看數據是否同步過來了)
CONFIG GET slave-read-only? (查看從節點是否有寫操作);應該是沒有寫操作的權限,否則會造成數據的混亂不一致。
在上述實驗的基礎上實現高可用:
需要三臺監控的服務器來實現對三臺redis服務器的監控,監控機器的數為奇數,因為涉及到最后投票來確定主節點機器的服務確實是宕機了。為了防止一臺機器的主觀誤判。
當主服務器宕機時,選擇哪臺從服務器作為主機器,首先要看其優先級,如果優先級相同則去判斷他的IP,基于選舉協議來實行的。
當主節點當即之后,會重新選舉從節點變為主節點,此時其他的從節點要刪除已有的數據重新從現在的主節點上同步數據。
此實驗由于機器不夠,所以在主從的三臺機器上做配置了。
監控程序的端口號:port 26379
(開啟監控程序的服務)
在主節點:
vim /etc/redis-sentinel.conf? (修改監控的配置文件)
bind 0.0.0.0 ? 15行
sentinel monitor mymaster 192.168.60.20 6379 2 (監控主節點的IP地址及端口號和三臺監控設備,至少有兩臺投票說它宕機了,才切換到備用主機上)69 行
sentinel auth-pass mymaster lv? (設置主節點的驗證密碼)89行
sentinel parallel-syncs mymaster 5 (并行復制的節點數調整大一些)
systemctl start redis-sentinel (啟動監控服務)
ss -nult (查看端口號是否開啟了)
在從節點:
在note1上:
redis-cli -a lv? (登陸進數據庫)
config set slave-priority 90(將優先級改為90)
config rewrite? (將更改的數據進行保存)
config get slave-priority? (驗證是否生效)
vim /etc/redis-sentinel.conf (修改監控的配置文件)
修改的內容和主節點上的一樣
systemctl start redis-sentinel (啟動監控服務)
ss -nult (查看端口號是否開啟了)
note2
vim /etc/redis-sentinel.conf (修改監控的配置文件)
修改的內容和主節點上的一樣
systemctl start redis-sentinel (啟動監控服務)
ss -nult (查看端口號是否開啟了)
(三份相同的配置文件可以復制過去使用,但要注意:sentinel myid號是否相同,需要不同才可以,如果相同,將此行刪除之后重啟服務就可以生成新的id號了,在69行)
最后驗證查看:(任意一臺sentinel節點的機器上)
redis-cli -p 26379 (登陸到數據庫)
sentinel masters? (查看主節點機器的詳細信息)
sentinel slaves mymaster? (查看備用節點的詳細信息及個數)
模擬主節點宕機:手動將主節點的redis服務暫停:
此時在備用的從節點上登陸: redis-cli -p 26379
查看現在的主節點是那臺機器:sentinel masters? (可以發現主節點的機器變為備用的主的機器了)
此時將主節點機器修復后,在此添加進去,作為備用主機來用:
vim /etc/redis.conf (修改原來主節點的配置文件,讓其成為從節點使用)
slaveof 192.168.60.21 6379? (指定新的主節點機器的IP地址和端口號)266行
masterauth lv (指定新的主機點的密碼)273行
systemctl restart redis? (啟動服務)
此時到現在的主節點上去看,發現自己已經添加到備用節點上去了。
也可查從節點的日志信息:tail /var/log/redis/sentinel.log
以此類推實現了高可用的循環了。
redis的分布式擴展的方式;
本文來自投稿,不代表Linux運維部落立場,如若轉載,請注明出處:http://www.www58058.com/103358