?一、NoSQL基礎概念:
ACID:原子性、一致性、隔離性、持久性;
特性:數據量大、數據變化非常大(數據增長化、流量分布變化、數據間耦合結構變化)、數據源很多;
CAP、BASE
CAP C:多個數據節點的的數據一致;
A:用戶發出請求后的有限時間范圍內返回結果;
P:network partition,網絡發生分區后,服務是否依可用;
CAP理論:一個分布式系統不可能時滿足C、A、P三個特性,最多可同時滿足其中兩者
對于分布式系統滿足分區容錯性幾乎是必須的。
AP:放棄C,但并非全部放棄,是在一段時間不保證一致,但最終是一致的;
CP:放棄A,而提供高可用的服務器;
BASE:BA,S,E,基于CAP演化而來
BA:Basically Availabel,基本可用;
S:Soft state,軟狀態/柔性事務,即狀態可以在一個時間窗口內是不同步的;
E:Eventually consisitency,最終的一致性;
NoSQL:Not Only SQL
k/v:Dynamo,redis
document:文檔數據庫,mongodb
BraphDB:圖式數據庫,Neo4j
二、Redis簡介:
REmote DIctionary Server:數據結構服務器,k/v數據結構;
內存存儲:in-memory 持久化 主從(sentinel) Cluster(shard)
數據結構服務器:
String,Lists,Hashs,Sets,Sorted Sets,Bitmaps,Hyperloglogs
PUB/SUB
單進程:CPU并非瓶頸;
持久化: snapshotting AOF
Replication: 主/從 主:rw 從:read-only程序環境
配置文件:/etc/redis.conf
主程序:/usr/bin/rdis-server 監聽端口 6379/tcp
客戶端:/usr/bin/redis-cli
Unit File: /usr/lib/systemd/system/reids.service
數據目錄: /var/lib/redis
redis: k/v
key:直接ASCII字符串;
value:strings,litst,hashes,sets,sotred sets,bitmaps,hyperloglogs
group:
@generice,@string,@list,@…
@string | @list | @set | @sorted_set | @hash |
SET | LPUSH | SADD | ZADD | HSET |
GET | RPUSH | SPOP | ZCARD | HGET |
EXISTS | LPOR | SREM | ZCOUNT | HMGET |
NCRI | RPOP | SRANDMEMBER | ZRANK | HKEYS |
DECR | LINDEX | SINTER | HVALS | |
LSET | SUNION | ?HDEL | ||
HGETALL |
配置和使用redis:
/etc/redis.conf的配置項
基本配置項,網絡配置項,持久化相關配置,復制相關的配置,安全相關的配置,Limit相關的配置
SlowLog相關的配置 INCLUDES Advanced配置
通用配置項:
daemonize,supervised,loglevel,pidfile,logfile
database,設定數據庫數量,默認為16個,每個數據庫的名字均為整數,從0開始編號,默認操作的數據庫為0;
切換數據庫的方法:SELECT<dbid>
網絡配置項:bind IP 、 port PORT 、 protected-mode 、tcp-backlog 、 Unixsocket 、timeoute(連接空閑的超時時長)
安全配置:requirepass:<PASSWORD> rename-command:<COMMAND><NEW_CMND_NAME>在AOF或Replication環境中,不推薦使用;
Limits相關的配置:
maxclients maxmemory<bytes> maxmemory-policy noevication
淘汰策略:volatile-lru,allkeys-lru,volatile-random,allkeys-random,volatile-ttl,noeviction
maxmemory-sample 5 淘汰算法運行的采樣樣本數;
SlowLog相關的配置:
slowlog-log-slower-than 10000 單位是微秒;
slow-max-len 128
SlowLog記錄的日志是最大條目;
ADVANCED配置;
hash-max-ziplist-entries 512
hash-max-ziplist-value 64 設置ziplist的鍵數量最大值,每個值的最大空間;
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
<hard-limit>
<soft-limit>
<soft-limit-seconds>
redis-cli命令:
Usage: redis-cli [OPTIONS] [cmd [arg [arg …]]]
-h HOST -p PORT -a PASSWORD -n DBID
與Connection相關的命令;
AUTH<password> ECHO<message> PING QUIT SELECT dbid
清空數據庫命令(小心使用):
FLUSHD: Remove all keys from the current,database ;
FLUSHALL: Remove all keys from all databases;
Server相關的命令:
CLIENT GETNAME ? *CLIENT KILL *CLIENT LIST ?LIENT PAUSE CLIENT REPLY
CLIENT SETNAME:Set the current connection name
CONFIG GET ? CONFIG RESETSTAT ? CONFIG REWRITE ? CONFIG SET
INFO:服務器狀態信息查看;分為多個session ;
INFO [section]
Redis的持久化;
RDB:snapshotting,二進制格式;按事先定制的策略,周期性地將數據從內存同步至磁盤;數據文件默認是dump,rdb;
客戶端顯示使用SAVA或BGSAVE命令來手動啟動快照 保存機制 ;
SAVE:同步,即在主線程中保存快照 ,此時會阻塞所有客戶端請求;
BGSAVE:異步;
AOF:Append Only FIle, fsync
記錄每次寫操作至指定的文件尾部實現的持久化,當redis重啟時,可能過重新執行文件中的命令在內存中重建 出數據庫;
BGREWRITEAOF:AOF文件重寫;
不會讀取正在使用AOF文件,而是通過將內存中的數據以命令的方式保存至臨時文件中,完成之后替換原來的AOF文件;
RDB相關的配置:
*save <seconds> <changes>
save 900 1
save 300 10
save 60 10000
這段配置的內容表示:三個策略滿足其中任意一個均會觸發SNAPSHOTTING操作;900s內至少有一個key有變化
300s內至少有10個key有變化,60s內至少有1萬個key發生變化;
stop-writes-on-bgsave-error yes dump操作出現錯誤時,是否禁止新寫入操作請求;
rdbcompression yes ?rdbchecksum yes
dbfilename dump.rdb: 指定rdb文件名
*dir /var/lib/redis:rdb文件的存儲路徑
AOF相關的配置
*appendonly no
appendfilename “appendonly.aof”
*appendfsync
Redis supports three different modes;
no:redis不執行主動同步操作,而是OS進行;
everysec:每秒一次;
always:每語句一次;
no-appendfsync-on-rewrite no
是否在后臺執行aof重寫期間不調用fsync,默認no,表示調用;
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
上述兩個條件同時滿足時,會觸發重寫AOF;與上次aof文件大小相比,其增長量超過100%,且大小不少于64MB;
aof-load-truncated yes
注意:持久機制本身不能取代備份;應該制訂備份策略;對redis庫定期備份;
RDB與AOF同時啟用;
(1)BGSAVE和BGREWRITEAOF不會同時進行;
(2)Redis服務器啟動時用持久化的數據文件恢復數據,會優先使用AOF;
復制:
特點:一個Master可以有多個slave主機,支持鏈式復制;
Master以非阻塞方式同步數據至slave主機;
配置slave節點;
redis-cli> SLAVEOF <MASTER_IP> <MASTER_PORT>
redis-cli> CONFIG SET Masterauth <PASSWORD>
sentinel:主要完成三個功能:監控、通知、自動故障轉移;
選舉方式:流言協議、投票協議;
配置項:
port 26379
sentinel monitor <master-name> <ip> <redis-port> <quorum>
sentinel auth-pass <master-name> <passowrd>
<quorum>表示sentinel集群的quorum機制,即至少有quorum個sentinel節點同時判定主節點故障時, 才認為其真的故障
s_down:subjectively down
o_down: objectively down
sentinel down-after-milliseconds <master-name><milliseconds>
監控到指定的集群的主節點異常狀態持續多久才將標記為“故障”;
sentinel parallel-syncs <master-name> <numslaves>
指在failover過程中,能夠被sentinel并行配置的從節點的數量;
sentinel failover-time <master-name> <milliseconds>
sentinel必須在此指定的時長內完成故障轉移操作, 否則,將視為故障轉移操作失??;
sentinel notification-scripts <master-name> <script-path>
通知腳本,此腳本被自動傳遞多個參數;
redis-cli -h SENITINEL_HOST -p SENTINEL_PORT
redis-cli>
SENTINEL masters
SENTINEL slaves <MASTER_NAME>
SENTINEL failover <MASTER_NAME>
SENTINEL get-master-addr-by-name <MASTER_NAME>
三、配置及安裝
注:各主機的/etc/hosts文件如下
192.168.36.128 node1
192.168.36.129 node2
192.168.36.130 node3
本次測試的ansible hosts文件配置如下
[node]
node1
node2
node3
下載安裝包 redis-3.2.3-1.el7.x86_64.rpm
# ansible node -m copy -a "src=/root/redis-3.2.3-1.el7.x86_64.rpm dest=/root" # for i in {1..3} ; do ssh node$i "yum -y install /root/redis-3.2.3-1.el7.x86_64.rpm" ; done # vim /etc/redis.conf 主服務器端,需要修改以下的幾項 bind 0.0.0.0 masterauth centos.123 設置此臺服務器當成為從服務器時,連接主而需要的密碼; slave-serve-stale-data yes requirepass centos.123 repl-diskless-sync no repl-diskless-sync-delay 5 repl-ping-slave-period 10 repl-timeout 60 repl-disable-tcp-nodelay no repl-backlog-size 1mb slave-priority 100 min-slaves-to-write 3 min-slaves-max-lag 10 將/etc/redis.conf 分發到其它三個從結點的 /etc/redis.conf,然后啟動服務 # ansible node -m copy -a "src=redis.conf dest=/etc/redis.conf " # ansible node -m service -a "name=redis state=started" 此時,可以啟用 /etc/ansible/hosts 中的node1 [root@node1 ~]# ansible node -m shell -a "ss -tnl | grep 6379" node1 | success | rc=0 >> LISTEN 0 128 *:6379 *:* node3 | success | rc=0 >> LISTEN 0 128 *:6379 *:* node2 | success | rc=0 >> LISTEN 0 128 *:6379 *:* 手動配置node2,node3三個從結點 [root@node2 ~]# redis-cli 127.0.0.1:6379> SLAVEOF 172.16.23.10 6379 127.0.0.1:6379> CONFIG SET masterauth centos.123 [root@node3 ~]# redis-cli 127.0.0.1:6379> SLAVEOF 172.16.23.10 6379 127.0.0.1:6379> CONFIG SET masterauth centos.123
通過以上的端口信息,可以看出四臺主機的已經正常啟動了
查看主結點的工作信息
[root@node1 ~]# redis-cli 127.0.0.1:6379> AUTH centos.123 OK 127.0.0.1:6379> INFO Replication # Replication role:master connected_slaves:3 min_slaves_good_slaves:3 slave0:ip=172.16.23.12,port=6379,state=online,offset=3641,lag=1 slave1:ip=172.16.23.13,port=6379,state=online,offset=3641,lag=1 slave2:ip=172.16.23.11,port=6379,state=online,offset=3641,lag=1 master_repl_offset:3641 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:2 repl_backlog_histlen:3640
查看其它兩個結點的信息
[root@node2 ~]# redis-cli 127.0.0.1:6379> AUTH centos.123 OK 127.0.0.1:6379> INFO Replication # Replication role:slave master_host:172.16.23.10 node1這臺從服務器指向 node0(172.16.23.10) 這臺主機 master_port:6379 master_link_status:up master_last_io_seconds_ago:7 master_sync_in_progress:0 slave_repl_offset:3865 slave_priority:100 slave_read_only:1 connected_slaves:0 min_slaves_good_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@node3 ~]# redis-cli 127.0.0.1:6379> AUTH centos.123 OK 127.0.0.1:6379> INFO Replication # Replication role:slave master_host:172.16.23.10 node2主服器也指上node0 master_port:6379 master_link_status:up master_last_io_seconds_ago:5 master_sync_in_progress:0 slave_repl_offset:365 slave_priority:100 slave_read_only:1 connected_slaves:0 min_slaves_good_slaves:0 master_repl_offset:0 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379>
至此為至redis主/從已經實現
接下來在三個結點上配置sentinel,實現故障轉移。此處實現累似于MariaDB的MHA
# vim /etc/redis-sentinel.conf 修改以下參數 sentinel monitor mymaster 192.168.36.130 6379 3 注(若redis-sentinel只在一個結點上安裝時,這里應該是 1,因為只有一個臺服務器結點可以滿足切換服務的要求) sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 18000 sentinel auth-pass mymaster centos.123 [root@node1 ~]# ansible node -m copy -a "src=/etc/redis-sentinel.conf dest=/etc/" [root@node1 ~]# ansible node -m service -a "name=redis-sentinel state=started" [root@node1 ~]# ansible node -m shell -a "ss -tnl | grep 26379" 查看四個結點的redis-sentinel服務是否啟動 node1 | success | rc=0 >> LISTEN 0 128 *:26379 *:* LISTEN 0 128 :::26379 :::* node2 | success | rc=0 >> LISTEN 0 128 *:26379 *:* LISTEN 0 128 :::26379 :::* node3 | success | rc=0 >> LISTEN 0 128 *:26379 *:* LISTEN 0 128 :::26379 :::* [root@node1 etc]# redis-cli -p 26379 此時可以看出redis的主結點在node1上 127.0.0.1:26379> SENTINEL masters 1) 1) "name" 2) "mymaster" 3) "ip" 4) "172.16.23.10" 5) "port" 6) "6379" 7) "runid" 8) "7e2c542c1bdef470ce53246ee4e4906b08add3d3" 9) "flags" 10) "master"
在node1上執行systemctl stop redis時,主自動切換主服務器
[root@node1 etc]# redis-cli -p 26379 此時可以看出redis的主結點在node3上 127.0.0.1:26379> SENTINEL masters 1) 1) "name" 2) "mymaster" 3) "ip" 4) "172.16.23.13" 5) "port" 6) "6379" 7) "runid" 8) "15f8f4ca4f7f907bf420a01a21d52733aed476d3" 9) "flags" 10) "master"
在node3上執行
[17:10:30root@node3~]#iptables -I INPUT -d 192.168.36.130 -p tcp --dport 6379 -j REJECT [root@node0 etc]# redis-cli -p 26379 此時可以看出reids的主結點在node1上 127.0.0.1:26379> SENTINEL masters 1) 1) "name" 2) "mymaster" 3) "ip" 4) "172.16.23.11" 5) "port" 6) "6379" 7) "runid" 8) "7d44ebc0898fbac4f31895b928f8a321d7599477" 9) "flags" 10) "master"
在node1上查看主/從信息
[root@node2 ~]# redis-cli 127.0.0.1:6379> AUTH centos.123 OK 127.0.0.1:6379> INFO Replication # Replication role:master connected_slaves:1 min_slaves_good_slaves:1 slave0:ip=192.168.36.129,port=6379,state=online,offset=34328,lag=1 master_repl_offset:34467 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:20961 repl_backlog_histlen:13507
原創文章,作者:nene,如若轉載,請注明出處:http://www.www58058.com/90847