1. 程式人生 > 其它 >DAY 104 redis高階02

DAY 104 redis高階02


es
rabbitmq,python中實現rpc
mongodb
mysql主從
django讀寫分離
cmdb
分庫分表(mycat)
redis分散式鎖
分散式id生成


1 redis持久化

1.1 rdb方案

快照:某時某刻資料的一個完成備份
-mysql的Dump
-redis的RDB
寫日誌:任何操作記錄日誌,要恢復資料,只要把日誌重新走一遍即可
-mysql的 Binlog
-Redis的 AOF


# rdb:快照方案
-save # 在客戶端輸入(同步)
-bgsave # 非同步(後臺持久化)
-配置檔案
save 900 1
save 300 10
save 60 10000
# 解釋
如果60s中改變了1w條資料,自動生成rdb
如果300s中改變了10條資料,自動生成rdb
如果900s中改變了1條資料,自動生成rdb
以上三條符合任意一條,就自動生成rdb,內部使用bgsave

1.2 aof方案

# 1 客戶端每寫入一條命令,都記錄一條日誌,放到日誌檔案中,如果出現宕機,可以將資料完全恢復

# 2 aof的三種策略
日誌不是直接寫到硬碟上,而是先放在緩衝區,緩衝區根據一些策略,寫到硬碟上
always:redis–》寫命令重新整理的緩衝區—》每條命令fsync到硬碟—》AOF檔案
everysec(預設值):redis——》寫命令重新整理的緩衝區—》每秒把緩衝區fsync到硬碟–》AOF檔案
no:redis——》寫命令重新整理的緩衝區—》作業系統決定,緩衝區fsync到硬碟–》AOF檔案


# 3 AOF重寫
本質就是把過期的,無用的,重複的,可以優化的命令,來優化
這樣可以減少磁碟佔用量,加速恢復速度

# aof持久化+aof重寫策略開啟的配置
appendonly yes #將該選項設定為yes,開啟
appendfilename "appendonly.aof" #檔案儲存的名字
appendfsync everysec #採用第二種策略
dir /bigdiskpath #存放的路徑
no-appendfsync-on-rewrite yes #在aof重寫的時候,是否要做aof的append操作,因為aof重寫消耗效能,磁碟消耗,正常aof寫磁碟有一定的衝突,這段期間的資料,允許丟失



##### rdb和aof都開啟了,以aof為準,rdb就不載入了

2 主從複製


### 原理
1. 副本庫通過slaveof 127.0.0.1 6379命令,連線主庫,併發送SYNC給主庫
2. 主庫收到SYNC,會立即觸發BGSAVE,後臺儲存RDB,傳送給副本庫
3. 副本庫接收後會應用RDB快照
4. 主庫會陸續將中間產生的新的操作,儲存併發送給副本庫
5. 到此,我們主複製集就正常工作了
6. 再此以後,主庫只要發生新的操作,都會以命令傳播的形式自動傳送給副本庫.
7. 所有複製相關資訊,從info資訊中都可以查到.即使重啟任何節點,他的主從關係依然都在.
8. 如果發生主從關係斷開時,從庫資料沒有任何損壞,在下次重連之後,從庫傳送PSYNC給主庫
9. 主庫只會將從庫缺失部分的資料同步給從庫應用,達到快速恢復主從的目的


## 主庫是否要開啟持久化
如果不開有可能,主庫重啟操作,造成所有主從資料丟失!


## 配置方案有兩種
第一通過命令:(啟動兩個redis例項),臨時的,重啟失效
在從庫上敲:
slaveof 127.0.0.1 6379 # 建立主從關係

slaveof no one # 取消主從關係


第二通過配置檔案
slaveof 127.0.0.1 6379
slave-read-only yes
# 如果主庫開啟了密碼認證,從庫需要加
# 主庫
requirepass 123456
# 從庫
masterauth 123456

2.3 django使用多redis

from django.core.cache import cache
from django.core.cache import caches
import random
def muti_cache(request):
#res_key=cache.get('res_key')
res_key=caches['redis'].get('res_key')
#res_key=caches['default'].get('res_key')
if not res_key:
res_key = random.randint(0,100)
cache.set('res_key','cache_key', 300)

3 哨兵高可用

# 原理
1 多個sentinel發現並確認master有問題
2 選舉觸一個sentinel作為領導
3 選取一個slave作為新的master
4 通知其餘slave成為新的master的slave
5 通知客戶端主從變化
6 等待老的master復活成為新master的slave


# sentinel是一個特殊的服務端,啟動也需要配置檔案

# 配置(三個哨兵配置檔案)

port 26379
daemonize yes
dir /opt/soft/redis/data
logfile "redis_sentinel_26379.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

port 26380
daemonize yes
dir /opt/soft/redis/data
logfile "redis_sentinel_26380.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000

port 26381
daemonize yes
dir /opt/soft/redis/data
logfile "redis_sentinel_26381.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000


## 啟動三個哨兵
./src/redis-sentinel redis_sentinel_26379.conf
./src/redis-sentinel redis_sentinel_26380.conf
./src/redis-sentinel redis_sentinel_26381.conf

## 提前搭好一主兩從

python操作redis哨兵

import redis
from redis.sentinel import Sentinel

# 連線哨兵伺服器(主機名也可以用域名)
# 10.0.0.101:26379
sentinel = Sentinel([('101.133.225.166', 26379),
('101.133.225.166', 26380),
('101.133.225.166', 26381)
],
socket_timeout=5)

# print(sentinel)
# # 獲取主伺服器地址
master = sentinel.discover_master('mymaster')
print(master)

# 獲取從伺服器地址
slave = sentinel.discover_slaves('mymaster')
print(slave)



##### 讀寫分離
# 獲取主伺服器進行寫入
# master = sentinel.master_for('mymaster', socket_timeout=5)
#
# print(type(master))
# # print(master)
# w_ret = master.set('foo', 'bar')

slave = sentinel.slave_for('mymaster', socket_timeout=0.5)
print(slave)
r_ret = slave.get('foo')
# print(r_ret)