Redis2 GEO, redis持久化(rdb,aof), redis主從, redis哨兵
阿新 • • 發佈:2020-12-02
GEO
儲存經緯度,計算兩個點之間的距離,統計某個點周圍多少距離的其他點
北京:116.28,39.55
天津:117.12,39.08
5個城市緯度
城市 | 經度 | 緯度 | 簡稱 |
---|---|---|---|
北京 | 116.28 | 39.55 | beijing |
天津 | 117.12 | tianjin | |
石家莊 | 114.29 | 38.02 | shijiazhuang |
唐山 | 118.01 | 39.38 | tangshan |
保定 | 115.29 | 38.51 | baoding |
geoadd key longitude latitude member 舉例: geoadd cities:locations116.28 39.55 beijing --你實際的專案,地理位置資訊從哪裡來的?前端傳過來的 -app,移動端,申請許可權,使用者允許了,直接呼叫手機提供的介面,得到經緯度---》調後臺介面傳給你--》拿到經緯度,放到redis中即可
(網頁也是,問是否允許訪問你的位置,選是返回後端) # 我現在是張三,我跟李四是朋友---》李四所在的位置,李四距離我多遠,我方圓5公里內,我的好友有誰 取出某個位置的座標 (把經緯度通過介面給前端, 前端自己處理。或者用post模組調網上現成介面[很多]顯示是哪裡,再給前端) geopos cities:locations beijing 計算兩個人之間的距離(算的是直線距離) geodist cities:locations beijing tianjin km 計算方圓多少公里內有誰(可以算房源,商鋪,好友) georadiusbymember cities:locations beijing150 km type cities:locations # 檢視geo是什麼型別,返回zset,是有序集合型別
相關命令
geoadd key longitude latitude member #增加地理位置資訊 geoadd cities:locations 116.28 39.55 beijing #把北京地理資訊天津到cities:locations中 geoadd cities:locations 117.12 39.08 tianjin geoadd cities:locations 114.29 38.02 shijiazhuang geoadd cities:locations118.01 39.38 tangshan geoadd cities:locations 115.29 38.51 baoding geopos key member #獲取地理位置資訊 geopos cities:locations beijing #獲取北京地理資訊 geodist key member1 member2 [unit]#獲取兩個地理位置的距離 unit:m(米) km(千米) mi(英里) ft(尺) geodist cities:locations beijing tianjin km #北京到天津的距離,89公里 georadius key logitude latitude radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key][storedist key] georadiusbymember key member radiusm|km|ft|mi [withcoord] [withdist] [withhash] [COUNT count] [asc|desc] [store key][storedist key] #獲取指定位置範圍內的地理位置資訊集合 ''' withcoord:返回結果中包含經緯度 withdist:返回結果中包含距離中心節點位置 withhash:返回解僱中包含geohash COUNT count:指定返回結果的數量 asc|desc:返回結果按照距離中心店的距離做升序/降序排列 store key:將返回結果的地理位置資訊儲存到指定鍵 storedist key:將返回結果距離中心點的距離儲存到指定鍵 ''' georadiusbymember cities:locations beijing 150 km ''' 1) "beijing" 2) "tianjin" 3) "tangshan" 4) "baoding" '''
3.2以後版本才有
geo本質時zset型別
可以使用zset的刪除,刪除指定member:zrem cities:locations beijing
redis持久化
#1 持久化:把記憶體中的資料,儲存到硬碟上 #2 兩種方案: -快照:rdb (類似mysql中的Dump,把記憶體中所有資料存到硬碟中) -日誌:aof (每加,修改一條記錄,記一條日誌。用來恢復資料,從頭走一遍即可恢復)
RDB
# 3 rdb持久化:三種方式,兩種手動,一種配置檔案(配置檔案) # 第一種:在redis-cli客戶端敲save---》通過rdb方案持久化到硬碟上,同步操作,會造成redis的阻塞 # (檔案策略:如果老的RDB存在,會替換老的) # 第二種:在redis-cli客戶端敲bgsave---》通過rdb方案持久化到硬碟上,非同步操作 # (檔案策略:跟save相同,如果老的RDB存在,會替換老的) # 第三種:配置檔案 save 900 1 save 300 10 save 60 10000 解釋: 如果60s中改變了1w條資料,自動生成rdb,自動呼叫一下bgsave 如果300s中改變了10條資料,自動生成rdb,自動呼叫一下bgsave 如果900s中改變了1條資料,自動生成rdb,自動呼叫一下bgsave # 配置檔案中加入: save 900 1 #配置一條 save 300 10 #配置一條 save 60 10000 #配置一條 dbfilename dump.rdb # 設定啟動載入的rdb檔名字,這句不寫預設為dump.rdb dir ./ #rdb檔案存在當前目錄 # 4 rdb方案有缺陷,可能會丟失資料(只是用快取)
刪除對應檔案,對應aof,rdb方式無法恢復
AOF
# 5 aof持久化方案 ## AOF介紹:客戶端每寫入一條命令,都記錄一條日誌,放到日誌檔案中,如果出現宕機,可以將資料完全恢復 ## aof的三種策略 日誌不是直接寫到硬碟上,而是先放在緩衝區,緩衝區根據一些策略,寫到硬碟上 always:redis--》寫命令重新整理的緩衝區---》每條命令fsync到硬碟---》AOF檔案 #耗費資源,每一條命令,調flash everysec(預設值):redis——》寫命令重新整理的緩衝區---》每秒把緩衝區fsync到硬碟--》AOF檔案 #每秒刷一次(一般用這個) no:redis——》寫命令重新整理的緩衝區---》作業系統決定,緩衝區fsync到硬碟--》AOF檔案 #類似python讀寫檔案,沒調flash,由系統決定 # 6 aof重寫 隨著命令的逐步寫入,併發量的變大, AOF檔案會越來越大,通過AOF重寫來解決該問題 本質就是把過期的,無用的,重複的,可以優化的命令,來優化 這樣可以減少磁碟佔用量,加速恢復速度 # 7 啟用aof就是修改一下配置檔案(重啟即可) appendonly yes #將該選項設定為yes,開啟 # appendfilename "appendonly-${port}.aof" #檔案儲存的名字(指定aof檔名字) appendfilename "appendonly.aof" #檔案儲存的名字(指定aof檔名字) appendfsync everysec #採用第二種策略 dir /bigdiskpath #存放的路徑 no-appendfsync-on-rewrite yes #在aof重寫的時候,是否要做aof的append操作,因為aof重寫消耗效能,磁碟消耗,正常aof寫磁碟有一定的衝突,這段期間的資料,允許丟失(重寫策略,是否開啟) ## 公司裡可以aof rdb同時使用,就是耗費效能 自動化運維繫統,自動安裝redis,修改配置檔案, 給redis使用aof的持久化方案 點按鈕,切換成aof----》開啟配置檔案---》把那幾行寫入---》重啟redis服務 點個按鈕即可
redis主從
# 1 為了提高效能,擴充套件機器(讀寫分離,資料副本。一主一從,一主多從) # 2 資料流向是單向的,從master到slave # 3 兩種方式:(需要兩臺機器)(啟動兩個redis程序,分別監聽兩個埠) -第一種:在客戶端cli裡執行命令 -在本地起兩個redis服務(程序)6380是從,6379是主 # 6380從庫基礎配置修改如下 ## port 6380 # 修改埠 ## dir "/opt/soft/redis/data1" # 修改資料存放目錄 ## logfile 6380.log # 修改log檔名 # 監測兩個redis程序起來沒 ps aux|grep redis-server ## grep --color=auto redis-server 這是監測的程序 -登陸到從庫(6380庫, redis-cli -p 6380),執行 -slaveof 127.0.0.1 6379 # 主庫增刪該資料,從庫跟著改(在從庫寫入資料會報錯) -取消複製:slaveof no one -第二種:配置檔案 -在從節點(從資料庫)配置(重啟即可) slaveof ip port #配置從節點ip和埠 slave-read-only yes #從節點只讀,因為可讀可寫,資料會亂 slaveof 127.0.0.1 6379 slave-read-only yes # 4 一主多從呢?(從庫只能讀) 只需要在多個從庫上配置即可
redis哨兵
架構說明
可以做故障判斷,故障轉移,通知客戶端(其實是一個程序),客戶端直接連線sentinel的地址
1 多個sentinel發現並確認master有問題
2 選舉觸一個sentinel作為領導
3 選取一個slave作為新的master
4 通知其餘slave成為新的master的slave
5 通知客戶端主從變化
6 等待老的master復活成為新master的slave
# 1 哨兵是為了保證redis'服務的高可用,一個master掛掉,服務依然可以用 # 2 哨兵搭建步驟 -1 先做一主兩從 6379是主mastre 6380是從slave 6381是從slave -2 啟用哨兵(哨兵是一個redis程序,哨兵sentinel程序可以分別放在不同的機器上) ## 配置解釋: sentinel monitor <master-name> <ip> <redis-port> <quorum> 告訴sentinel去監聽地址為ip:port的一個master,這裡的master-name可以自定義,quorum是一個數字,指明當有多少個sentinel認為一個master失效時,master才算真正失效 sentinel auth-pass <master-name> <password> 設定連線master和slave時的密碼,注意的是sentinel不能分別為master和slave設定不同的密碼,因此master和slave的密碼應該設定相同。 sentinel down-after-milliseconds <master-name> <milliseconds> 這個配置項指定了需要多少失效時間,一個master才會被這個sentinel主觀地認為是不可用的。 單位是毫秒,預設為30秒 sentinel parallel-syncs <master-name> <numslaves> 這個配置項指定了在發生failover主備切換時最多可以有多少個slave同時對新的master進行 同步,這個數字越小,完成failover所需的時間就越長,但是如果這個數字越大,就意味著越 多的slave因為replication而不可用。可以通過將這個值設為 1 來保證每次只有一個slave 處於不能處理命令請求的狀態。 sentinel failover-timeout <master-name> <milliseconds> failover-timeout 可以用在以下這些方面: 1. 同一個sentinel對同一個master兩次failover之間的間隔時間。 2. 當一個slave從一個錯誤的master那裡同步資料開始計算時間。直到slave被糾正為向正確的master那裡同步資料時。 3.當想要取消一個正在進行的failover所需要的時間。 4.當進行failover時,配置所有slaves指向新的master所需的最大時間。不過,即使過了這個超時,slaves依然會被正確配置為指向master,但是就不按parallel-syncs所配置的規則來了。 # vim sentinel_26379.conf #建立一個sentinel的配置檔案 #26379埠--一個哨兵 配置檔案: port 26379 daemonize yes# 是否以守護程序的形式來跑 dir data# 資料存放目錄 protected-mode no#保護模式,寫不寫都行,現在不需要遠端連它 bind 0.0.0.0#繫結 logfile "redis_sentinel.log"#日誌存放路徑,在資料存放路徑下面 sentinel monitor mymaster 127.0.0.1 6379 2#mymaster名字隨便命 主master地址埠號 2代表要有兩個sntinel覺得你掛了,你才是掛了 sentinel down-after-milliseconds mymaster 30000#指定需要多少時間,master被這個sentinel主管地認為不可用.單位是毫秒,預設為30秒 sentinel parallel-syncs mymaster 1#設定failover主備切換時,多少slave同事對新master進行同步,數字越小,切換時間越長.注:在備份的slave不可用,設為1保證每次只有一個slave處於不能處理命令請求狀態.預設為1 sentinel failover-timeout mymaster 180000#同一個sentinel對同一個master兩次failover失敗之間的事件間隔,單位毫秒,用預設即可 #26380埠--一個哨兵 port 26380 daemonize yes dir data1 protected-mode no bind 0.0.0.0 logfile "redis_sentinel.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 #26381埠--一個哨兵 port 26381 daemonize yes dir data2 protected-mode no bind 0.0.0.0 logfile "redis_sentinel.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 -redis-sentinel 配置檔案來啟動哨兵 -啟動哨兵: redis-sentinel 配置檔案 # ./src/redis-sentinel sentinel_26379.conf # 命令在src路徑下 redis-sentinel sentinel_26379.conf redis-sentinel sentinel_26380.conf redis-sentinel sentinel_26381.conf # ps aux |grep redis # 檢視當前redis-sentinel程序 -從客戶端登入到一個哨兵上 redis-cli -p 26379 # 哨兵不能寫資料 -輸入info 最後一行看到 master0:name=mymaster,status=ok,address=127.0.0.1:6379,slaves=2,sentinels=3 # 顯示主資料庫地址埠,從資料庫數量,幾個哨兵 -把主庫手動停掉 shutdown -連到哨兵上,輸入info(主master自動變成了6381) master0:name=mymaster,status=ok,address=101.133.225.166:6381,slaves=4,sentinels=3#這是視訊結果,有問題 master0:name=mymaster,status=ok,address=127.0.0.1:6381,slaves=2,sentinels=3#這是我的正常結果,6381變為主。從庫還是有2,實際有一個已經被關閉了 -原來的主庫如果啟動,主庫會變為從庫,繼續執行redis服務(哨兵不能重啟redis服務,只能監控)(視訊碰到了問題:資料髒了) # python客戶端連線(直接連了主庫,主庫掛掉,不能改程式碼吧) import redis from redis.sentinel import Sentinel # 連線哨兵伺服器(主機名也可以用域名) # 10.0.0.101:26379 sentinel = Sentinel([('10.0.0.101', 26379), ('10.0.0.101', 26378), ('10.0.0.101', 26377) ],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=0.5) # w_ret = master.set('foo', 'bar') # # # slave = sentinel.slave_for('mymaster', socket_timeout=0.5) # r_ret = slave.get('foo') # print(r_ret)