日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java分布式篇4——Redis

發布時間:2025/3/12 java 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java分布式篇4——Redis 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java分布式篇4——Redis

1、互聯網架構的演變歷程

1.1、第一階段

數據訪問量不大,簡單的架構即可搞定!

1.2、第二階段

  • 數據訪問量大,使用緩存技術來緩解數據庫的壓力
  • 不同的業務訪問不同的數據庫

1.3、第三階段

  • 主從讀寫分離。 之前的緩存確實能夠緩解數據庫的壓力,但是寫和讀都集中在一個數據庫上,壓力又來了,一個數據庫負責寫,一個數據庫負責讀,分工合作,讓master(主數據庫)來響應事務性(增刪改)操作,讓slave(從數據庫)來響應非事務性 (查詢)操作,然后再采用主從復制來把master上的事務性操作同步到slave數據庫中

1.4、第四階段

  • mysql集群

2、Redis介紹

Redis 是一種運行速度很快,并發性能很強,并且運行在內存上的NoSql(not only sql)數據庫

redis的瓶頸是內存和帶寬,不是CPU

2.1、適用場景

  • 緩存,毫無疑問這是Redis當今最為人熟知的使用場景。在提升服務器性能方面非常有效;一 些頻繁被訪問的數據,經常被訪問的數據如果放在關系型數據庫,每次查詢的開銷都會很 大,而放在redis中,因為redis 是放在內存中的可以很高效的訪問
  • 排行榜,在使用傳統的關系型數據庫(mysql oracle 等)來做這個事兒,非常的麻煩,而利 用Redis的SortSet(有序集合)數據結構能夠簡單的搞定
  • 計算器/限速器,利用Redis中原子性的自增操作,我們可以統計類似用戶點贊數、用戶訪問 數等,這類操作如果用MySQL,頻繁的讀寫會帶來相當大的壓力;限速器比較典型的使用場 景是限制某個用戶訪問某個API的頻率,常用的有搶購時,防止用戶瘋狂點擊帶來不必要的壓力
  • 好友關系,利用集合的一些命令,比如求交集、并集、差集等。可以方便搞定一些共同好 友、共同愛好之類的功能
  • 簡單消息隊列,除了Redis自身的發布/訂閱模式,我們也可以利用List來實現一個隊列機制, 比如:到貨通知、郵件發送之類的需求,不需要高可靠,但是會帶來非常大的DB壓力,完全 可以用List來完成異步解耦
  • Session共享,以jsp為例,默認Session是保存在服務器的文件中,如果是集群服務,同一個 用戶過來可能落在不同機器上,這就會導致用戶頻繁登陸;采用Redis保存Session后,無論 用戶落在那臺機器上都能夠獲取到對應的Session信息

2.2、 Redis/Memcache/MongoDB對比

  • Redis和Memcache都是內存數據庫。不過memcache還可用于緩存其他東西,例如圖片、視頻等
  • memcache 數據結構單一kv,redis 更豐富一些,還提供 list,set, hash 等數據結構的存儲,有 效的減少網絡IO的次數
  • 虛擬內存–Redis當物理內存用完時,可以將一些很久沒用到的value交換到磁盤
  • 存儲數據安全–memcache掛掉后,數據沒了(沒有持久化機制);redis可以定期保存到磁盤(持久化)
  • mongodb本質上還是硬盤數據庫,在復雜查詢時仍然會有大量的資源消耗,而且在處理復雜邏輯 時仍然要不可避免地進行多次查詢,這時就需要redis或Memcache這樣的內存數據庫來作為中間層進行緩存和加速

3、CAP原理

  • C(Consistency):強一致性
    • “all nodes see the same data at the same time”,即更新操作成功并返回客戶端后,所 有節點在同一時間的數據完全一致,這就是分布式的一致性。一致性的問題在并發系統 中不可避免,對于客戶端來說,一致性指的是并發訪問時更新過的數據如何獲取的問 題。從服務端來看,則是更新如何復制分布到整個系統,以保證數據最終一致
  • A(Availability):高可用性
    • 可用性指“Reads and writes always succeed”,即服務一直可用,而且要是正常的響應 時間。好的可用性主要是指系統能夠很好的為用戶服務,不出現用戶操作失敗或者訪問 超時等用戶體驗不好的情況
  • P(Partition tolerance):分區容錯性
    • 即分布式系統在遇到某節點或網絡分區故障時,仍然能夠對外提供滿足一致性或可用性 的服務。 分區容錯性要求能夠使應用雖然是一個分布式系統,而看上去卻好像是在一個可以運轉 正常的整體。比如現在的分布式系統中有某一個或者幾個機器宕掉了,其他剩下的機器 還能夠正常運轉滿足系統需求,對于用戶而言并沒有什么體驗上的影響

3.1、CAP總結

根據 CAP 原理將 NoSQL 數據庫分成了滿足 CA 原則、滿足 CP 原則和滿足 AP 原則三大類

  • CA - 單點集群,滿足一致性,可用性的系統,通常在可擴展性上不太強大
  • CP - 滿足一致性,分區容忍性的系統,通常性能不是特別高
  • AP - 滿足可用性,分區容忍性的系統,通常可能對一致性要求低一些

4、下載安裝(linux)

redis官網:https://www.redis.net.cn/

redis5.0.4 百度云:https://pan.baidu.com/s/1BfWTbuSQuBAiRK7CWS73Ow提取碼:2b45

4.1、解壓

tar -zxvf redis-5.0.4.tar.gz

4.2、安裝gcc

yum -y install gcc

4.3、進入redis目錄,編譯

make make install

4.4、redis默認不會使用后臺運行,如果你需要,修改配置文件daemonize=yes

vim redis.conf daemonize yes

4.5、默認安裝到的位置為

/usr/local/bin

4.6、拷貝配置文件,并指定配置文件啟動redis

[root@VM-8-13-centos bin]# cp /usr/local/redis-5.0.4/redis.conf redis.conf [root@VM-8-13-centos bin]# ls busybox-x86_64 redis-benchmark redis-check-aof redis-check-rdb redis-cli redis.conf redis-sentinel redis-server [root@VM-8-13-centos bin]# redis-server redis.conf 14566:C 31 Jul 2021 21:54:44.185 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 14566:C 31 Jul 2021 21:54:44.185 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=14566, just started 14566:C 31 Jul 2021 21:54:44.185 # Configuration loaded

4.7、測試

[root@VM-8-13-centos bin]# redis-cli -p 6379 127.0.0.1:6379> ping PONG 127.0.0.1:6379> exit

4.8、關閉

單實例

redis-cli shutdown

多實例

redis-cli -p 6379 shutdown

4.9、常用命令

檢測6379端口是否在監聽

netstat -lntp | grep 6379

檢測后臺進程是否存在

ps -ef|grep redis

5、性能測試

[root@VM-8-13-centos bin]# redis-benchmark ====== PING_INLINE ======# 1.8秒處理了10萬個請求100000 requests completed in 1.37 seconds50 parallel clients3 bytes payloadkeep alive: 199.79% <= 1 milliseconds 99.93% <= 2 milliseconds 100.00% <= 2 milliseconds # 每秒處理的請求 72886.30 requests per second====== PING_BULK ======100000 requests completed in 1.35 seconds50 parallel clients3 bytes payloadkeep alive: 199.66% <= 1 milliseconds 99.83% <= 2 milliseconds 99.85% <= 3 milliseconds 99.94% <= 4 milliseconds 100.00% <= 4 milliseconds 74349.44 requests per second

6、基礎命令

6.1、測試是否連通

127.0.0.1:6379> ping PONG

6.2、存值取值

127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> set k2 v2 OK 127.0.0.1:6379> get k1 "v1"

6.3、數據庫大小

127.0.0.1:6379> dbsize (integer) 5

6.4、數據庫所有值

127.0.0.1:6379> keys * 1) "mylist" 2) "key:__rand_int__" 3) "k2" 4) "k1" 5) "counter:__rand_int__"

6.5、清空數據庫

清空單一數據庫

127.0.0.1:6379> flushdb OK 127.0.0.1:6379> dbsize (integer) 0

清空所有數據庫

127.0.0.1:6379> flushall OK

6.6、存在值

127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> exists k1 (integer) 1 127.0.0.1:6379> exists k2 (integer) 0

6.7、過期時間

127.0.0.1:6379> expire k1 30 (integer) 1 127.0.0.1:6379> ttl k1 (integer) 19

ttl查看鍵還有多久過期

6.8、判斷數據類型

127.0.0.1:6379> set k1 123 OK 127.0.0.1:6379> get k1 "123" 127.0.0.1:6379> type k1 string

6.9、移除鍵

127.0.0.1:6379> del k1 (integer) 1 127.0.0.1:6379> get k1 (nil)

6.10、移動鍵到其他數據庫

127.0.0.1:6379> set k1 zhangsan OK 127.0.0.1:6379> move k1 1 (integer) 1 127.0.0.1:6379> get k1 (nil) 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> get k1 "zhangsan"

7、五大基本數據類型

7.1、String

7.1.1、存取刪

127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> get k1 "v1" 127.0.0.1:6379> del k1 (integer) 1

7.1.2、追加

若不存在,則會新建

127.0.0.1:6379> set k1 v1 OK 127.0.0.1:6379> append k1 zhangsan (integer) 10 127.0.0.1:6379> get k1 "v1zhangsan"

7.1.3、字符串長度

127.0.0.1:6379> strlen k1 (integer) 10

7.1.4、自增自減

127.0.0.1:6379> set k1 1 OK 127.0.0.1:6379> incr k1 (integer) 2 127.0.0.1:6379> get k1 "2" 127.0.0.1:6379> decr k1 (integer) 1 127.0.0.1:6379> get k1 "1" 127.0.0.1:6379> incrby k1 10 (integer) 11 127.0.0.1:6379> get k1 "11" 127.0.0.1:6379> decrby k1 10 (integer) 1 127.0.0.1:6379> get k1 "1"

7.1.5、截取字符串

127.0.0.1:6379> set k1 abhbfhbysydvsd OK 127.0.0.1:6379> getrange k1 0 -1 "abhbfhbysydvsd" 127.0.0.1:6379> getrange k1 0 3 "abhb"

7.1.6、替換值

127.0.0.1:6379> setrange k1 0 HHHH (integer) 14 127.0.0.1:6379> get k1 "HHHHfhbysydvsd"

7.1.7、添加數據并設置生命周期

setex(set with expir)

127.0.0.1:6379> setex k1 30 abc OK 127.0.0.1:6379> ttl k1 (integer) 24

7.1.8、如果不存在才添加

setnx(set if not exist)

127.0.0.1:6379> setnx k2 v2 (integer) 0 127.0.0.1:6379> get k2 "v2"

7.1.9、一次添加多個值

mset/mget/msetnx

127.0.0.1:6379> mset k1 v1 k2 v2 OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 127.0.0.1:6379> mget k1 k2 1) "v1" 2) "v2"

7.1.10、先取后存

127.0.0.1:6379> getset k1 vv1 "v1"

7.2、List

允許有重復元素

7.2.1、lpush存(—>)

127.0.0.1:6379> lpush list1 1 2 3 4 5 (integer) 5

7.2.2、查(—>)

127.0.0.1:6379> lrange list1 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1"

7.2.3、rpush存

127.0.0.1:6379> rpush list1 0 (integer) 6 127.0.0.1:6379> lrange list1 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 5) "1" 6) "0"

7.2.4、lpop取(<—)

127.0.0.1:6379> lpop list1 "5" 127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 5) "0"

7.2.4、rpop取(—>)

127.0.0.1:6379> rpop list1 "0" 127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 4) "1"

7.2.5、按下標取(<—)

127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 127.0.0.1:6379> lindex list1 0 "4"

7.2.6、集合長度

127.0.0.1:6379> lrange list1 0 -1 1) "4" 2) "3" 3) "2" 4) "1" 127.0.0.1:6379> llen list1 (integer) 4

7.2.7、刪除指定個數指定的值

127.0.0.1:6379> lpush list2 1 1 2 2 2 3 3 3 4 4 4 (integer) 11 127.0.0.1:6379> lrange list2 0 -11) "4"2) "4"3) "4"4) "3"5) "3"6) "3"7) "2"8) "2"9) "2" 10) "1" 11) "1" 127.0.0.1:6379> lrem list2 2 2 (integer) 2 127.0.0.1:6379> lrange list2 0 -1 1) "4" 2) "4" 3) "4" 4) "3" 5) "3" 6) "3" 7) "2" 8) "1" 9) "1"

7.2.8、修建集合

127.0.0.1:6379> lrange list2 0 -1 1) "4" 2) "4" 3) "4" 4) "3" 5) "3" 6) "3" 7) "2" 8) "1" 9) "1" 127.0.0.1:6379> ltrim list2 1 8 OK 127.0.0.1:6379> lrange list2 0 -1 1) "4" 2) "4" 3) "3" 4) "3" 5) "3" 6) "2" 7) "1" 8) "1"

7.2.9、彈出一個元素加入另外一個list集合

127.0.0.1:6379> lpush list1 1 2 3 4 5 (integer) 5 127.0.0.1:6379> lpush list2 one two three four five (integer) 5 127.0.0.1:6379> rpoplpush list1 list2 "1" 127.0.0.1:6379> lrange list1 0 -1 1) "5" 2) "4" 3) "3" 4) "2" 127.0.0.1:6379> lrange list2 0 -1 1) "1" 2) "five" 3) "four" 4) "three" 5) "two" 6) "one"

7.2.10、設置指定索引的值

127.0.0.1:6379> lrange list1 0 -1 1) "555" 2) "4" 3) "3" 4) "2" 127.0.0.1:6379> lset list1 1 444 OK 127.0.0.1:6379> lrange list1 0 -1 1) "555" 2) "444" 3) "3" 4) "2"

7.2.11、在指定值前插入數值

127.0.0.1:6379> lrange list1 0 -1 1) "555" 2) "444" 3) "3" 4) "2" 127.0.0.1:6379> linsert list1 before 555 999 (integer) 5 127.0.0.1:6379> lrange list1 0 -1 1) "999" 2) "555" 3) "444" 4) "3" 5) "2" 127.0.0.1:6379> linsert list1 after 555 999 (integer) 6 127.0.0.1:6379> lrange list1 0 -1 1) "999" 2) "555" 3) "999" 4) "444" 5) "3" 6) "2"

7.3、Set

無序不重復(此無序不是指的set無序,而是指沒有插入順序)

7.3.1、存

127.0.0.1:6379> sadd set1 5 8 6 3 1 9 (integer) 6

7.3.2、取

127.0.0.1:6379> smembers set1 1) "1" 2) "3" 3) "5" 4) "6" 5) "8" 6) "9"

7.3.3、判斷值是否存在

127.0.0.1:6379> smembers set1 1) "1" 2) "3" 3) "5" 4) "6" 5) "8" 6) "9" 127.0.0.1:6379> sismember set1 9 (integer) 1 127.0.0.1:6379> sismember set1 7 (integer) 0

7.3.4、元素個數

127.0.0.1:6379> smembers set1 1) "1" 2) "3" 3) "5" 4) "6" 5) "8" 6) "9" 127.0.0.1:6379> sismember set1 9 (integer) 1 127.0.0.1:6379> scard set1 (integer) 6

7.3.5、移除元素

127.0.0.1:6379> srem set 6 (integer) 0 127.0.0.1:6379> smembers set1 1) "1" 2) "3" 3) "5" 4) "6" 5) "8" 6) "9"

7.3.6、隨機選值

127.0.0.1:6379> smembers set1 1) "1" 2) "3" 3) "5" 4) "6" 5) "8" 6) "9" 127.0.0.1:6379> srandmember set1 "5" 127.0.0.1:6379> srandmember set1 3 1) "6" 2) "3" 3) "9"

7.3.7、隨機移除值

127.0.0.1:6379> spop set1 "3" 127.0.0.1:6379> spop set1 3 1) "1" 2) "9" 3) "6" 127.0.0.1:6379> smembers set1 1) "5" 2) "8"

7.3.8、將指定的值從源set集合移動到目標set集合

127.0.0.1:6379> smembers set1 1) "5" 2) "8" 127.0.0.1:6379> sadd set2 one two (integer) 2 127.0.0.1:6379> smove set1 set2 5 (integer) 1 127.0.0.1:6379> smembers set1 1) "8" 127.0.0.1:6379> smembers set2 1) "5" 2) "one" 3) "two"

7.3.9、set集合1中set集合2沒有的元素

127.0.0.1:6379> sadd set1 1 5 6 9 7 3 (integer) 6 127.0.0.1:6379> sadd set2 3 5 8 4 10 2 (integer) 6 127.0.0.1:6379> sdiff set1 set2 1) "1" 2) "6" 3) "7" 4) "9"

7.3.10、set集合1中set集合2有的元素

127.0.0.1:6379> sadd set1 1 5 6 9 7 3 (integer) 6 127.0.0.1:6379> sadd set2 3 5 8 4 10 2 (integer) 6 127.0.0.1:6379> sinter set1 set2 1) "3" 2) "5"

7.3.11、set集合、set集合2所有的元素

127.0.0.1:6379> sadd set1 1 5 6 9 7 3 (integer) 6 127.0.0.1:6379> sadd set2 3 5 8 4 10 2 (integer) 6 127.0.0.1:6379> sunion set1 set21) "1"2) "2"3) "3"4) "4"5) "5"6) "6"7) "7"8) "8"9) "9" 10) "10"

7.4、Hash

7.4.1、存取

127.0.0.1:6379> hset hash1 k1 v1 (integer) 1 127.0.0.1:6379> hget hash1 k1 "v1" 127.0.0.1:6379> hmset hash1 k2 v2 k3 v3 OK 127.0.0.1:6379> hmget hash1 k1 k2 k3 1) "v1" 2) "v2" 3) "v3"

7.4.2、獲取所有鍵值對

127.0.0.1:6379> hgetall hash1 1) "k1" 2) "v1" 3) "k2" 4) "v2" 5) "k3" 6) "v3"

7.4.3、獲取長度

127.0.0.1:6379> hlen hash1 (integer) 3

7.4.4、判斷鍵是否存在

127.0.0.1:6379> hexists hash1 k1 (integer) 1 127.0.0.1:6379> hexists hash1 k4 (integer)

7.4.5、獲取所有鍵

127.0.0.1:6379> hkeys hash1 1) "k1" 2) "k2" 3) "k3"

7.4.6、獲取所有值

127.0.0.1:6379> hvals hash1 1) "v1" 2) "v2" 3) "v3"

7.4.7、如果不存在設置值

127.0.0.1:6379> hsetnx hash1 k4 v4 (integer) 1

7.5、Zset

有序set

7.5.1、存取

127.0.0.1:6379> zadd zset1 1 zhangsan (integer) 1 127.0.0.1:6379> zadd zset1 3 lisi 2 wangwu 4 zhaoliu (integer) 3 127.0.0.1:6379> zrange zset1 0 -1 1) "zhangsan" 2) "wangwu" 3) "lisi" 4) "zhaoliu" #逆序 127.0.0.1:6379> zrevrange zset1 0 -1 1) "zhaoliu" 2) "lisi" 3) "wangwu" 4) "zhangsan"

7.5.2、范圍

127.0.0.1:6379> zrangebyscore zset1 1 3 1) "zhangsan" 2) "wangwu" 3) "lisi" #取排序依據在1-3之間的值,跳過一個,取一個 127.0.0.1:6379> zrangebyscore zset1 1 3 limit 1 1 1) "wangwu"

7.5.3、刪除

127.0.0.1:6379> zrange zset1 0 -1 1) "zhangsan" 2) "wangwu" 3) "lisi" 4) "zhaoliu" 127.0.0.1:6379> zrem zset1 wangwu (integer) 1 127.0.0.1:6379> zrange zset1 0 -1 1) "zhangsan" 2) "lisi" 3) "zhaoliu"

7.5.4、集合長度

127.0.0.1:6379> zcard zset1 (integer) 3

7.5.5、獲取指定分數間元素的個數

127.0.0.1:6379> zcount zset1 2 3 (integer) 1

7.5.6、獲取指定元素的下標(從上到下)

127.0.0.1:6379> zrange zset1 0 -1 1) "zhangsan" 2) "lisi" 3) "zhaoliu" 127.0.0.1:6379> zrank zset1 lisi (integer) 1 127.0.0.1:6379> zrank zset1 zhangsan (integer) 0 #(從下到上) 127.0.0.1:6379> zrevrank zset1 zhangsan (integer) 2

7.5.7、獲取元素分數

127.0.0.1:6379> zscore zset1 lisi "3"

7.5.8、范圍查找

127.0.0.1:6379> zadd zset1 11 zhangsan 21 lisi 62 wangwu 30 zhaoliu 52 qianmqi (integer) 5 127.0.0.1:6379> zrangebyscore zset1 20 40 1) "lisi" 2) "zhaoliu" 127.0.0.1:6379> zrevrangebyscore zset1 40 20 1) "zhaoliu" 2) "lisi"

8、三大特殊數據類型

geospatial(地理位置)

  • geoadd 鍵 經度 緯度 名稱(添加一個地理位置)
  • geopos 鍵 名稱(獲取地理位置的經緯度)
  • geodist 鍵 名稱1 名稱2(獲取兩地的距離,單位m)
  • geodist 鍵 名稱1 名稱2 km(獲取兩地的距離,單位km)
  • georadius 鍵 經度 緯度 半徑 單位(根據指定經緯度和半徑查詢附近的人)
  • georadius 鍵 經度 緯度 半徑 單位 withdist(根據指定經緯度和半徑查詢附近的人,并攜帶距離)
  • georadius 鍵 經度 緯度 半徑 單位 withcoord(根據指定經緯度和半徑查詢附近的人,并攜帶經緯度)
  • georadius 鍵 經度 緯度 半徑 單位 withcoord count 1(根據指定經緯度和半徑查詢附近指定數量的人)
  • georaduisbymember 鍵 值 距離 單位(尋找指定位置指定距離內的城市)
  • geohash 鍵 值(將2維的經緯度轉換為1維的字符串,若字符串越接近,則距離越近)

hyperloglog(類似zset)

基數

  • pfadd 鍵 值1 值2 … 值n
  • pfcount 鍵
  • pfmerge 新hyperloglog hyperloglog1 hyperloglog2(合并hyperloglog)

Bitmaps(位存儲)

  • setbit 鍵 偏移 值
  • getbit 鍵 偏移
  • bitcount 鍵(統計為1的值)

9、持久化技術

9.1、RDB(redis默認選擇)

Redis DataBase

9.1.1、觸發機制

  • 使用shutdown命令,redis會自動將數據庫備份
  • 數據變更滿足redis.conf里的條件
    • save 900 1 # 900秒內,至少變更1次,會自動備份
    • save 300 10 # 120秒內,至少變更10次,會自動備份
    • save 60 10000 # 60秒內,至少變更10000次,會自動備份
  • save命令

9.1.2、配置詳解

  • stop-writes-on-bgsave-error:
    • yes:當后臺備份時候反生錯誤,前臺停止寫入
    • no:不管是否錯誤,都往里寫數據
  • rdbcompression:對于存儲到磁盤中的快照,是否啟動LZF壓縮算法,一般都會啟動
    • yes:啟動
    • no:不啟動(不想消耗CPU資源,可關閉)
  • rdbchecksum:在存儲快照后,是否啟動CRC64算法進行數據校驗;
    • yes:啟動
    • no:不啟動(不想消耗CPU資源,可關閉)
  • dbfilename:快照備份文件名字
  • dir:快照備份文件保存的目錄,默認為當前目錄

9.1.3、優缺點

優:適合大規模數據恢復,對數據完整性和一致行要求不高

劣:一定間隔備份一次,意外down掉,就失去最后一次快照的所有修改

9.2、AOF

Append Only File(將redis執行過的寫指令全部記錄下來讀操作不記錄,redis在啟動之初會讀取該文件從頭到尾執行一遍,這樣來重新構建數據)

9.2.1、開啟

redis.conf

appendonly yes appendfilename appendonly.aof

9.2.2、觸發機制

根據appendfsync規則

9.2.3、配置詳解

  • appendonly:是否開啟aof
    • yes
    • no
  • appendfilename:appendonly.aof aof備份的文件
  • appendfsync:追加策略
    • always:每次數據變更,就會立即記錄到磁盤,性能較差,但數據完整性好
    • everysec:默認設置,異步操作,每秒記錄,如果一秒內宕機,會有數據丟失
    • no:不追加
  • no-appendfsync-on-rewrite:重寫時是否運用Appendfsync追寫策略;用默認no即可,保證數據安全性
  • auto-aof-rewrite-percentage:如果AOF文件大小已經超過原來的100%,也就是一倍,才重寫壓縮
  • auto-aof-rewrite-min-size:64mb 如果AOF文件已經超過了64mb,才重寫壓縮

9.2.4、優缺點

  • 在最惡劣的情況下,也只丟失不超過2秒的數據,數據完整性比較高
  • 代價太大,會帶來持續的IO

10、事務

一次執行多個命令,是一個命令組,一個事務中,所有命令都會序列化(排隊),不會被插隊

三特性

  • 隔離性:所有命令都會按照順序執行,事務在執行的過程中,不會被其他客戶端送來的命令 打斷
  • 沒有隔離級別:隊列中的命令沒有提交之前都不會被實際的執行,不存在“事務中查詢要看到 事務里的更新,事務外查詢不能看到”這個頭疼的問題
  • 不保證原子性:冤有頭債有主,如果一個命令失敗,但是別的命令可能會執行成功,沒有回滾

10.1、提交事務

127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> set k3 v3 QUEUED 127.0.0.1:6379> get k3 QUEUED 127.0.0.1:6379> set k4 v4 QUEUED 127.0.0.1:6379> exec 1) OK 2) OK 3) OK 4) "v3" 5) OK

10.2、取消提交

127.0.0.1:6379> multi OK 127.0.0.1:6379> get k1 QUEUED 127.0.0.1:6379> set k2 v222 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> get k2 "v2"

10.3、命令出錯(編譯出錯)

取消所有執行內容

127.0.0.1:6379> multi OK 127.0.0.1:6379> set1231213 (error) ERR unknown command `set1231213`, with args beginning with: 127.0.0.1:6379> set k1 v111 QUEUED 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> get k1 "v1"

10.4、命令出錯(運行出錯)

錯誤的不執行,其他照舊執行

127.0.0.1:6379> multi OK 127.0.0.1:6379> set k1 v1 QUEUED 127.0.0.1:6379> incr k1 QUEUED 127.0.0.1:6379> set k2 v2 QUEUED 127.0.0.1:6379> exec 1) OK 2) (error) ERR value is not an integer or out of range 3) OK 127.0.0.1:6379> get k2 "v2" 127.0.0.1:6379> get k1 "v1"

11、監控

  • watch 鍵
  • multi(開啟事務)
  • exec(執行事務)

exec后會解鎖

12、發布訂閱

進程間的一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息

接收端

127.0.0.1:6379> subscribe cctv1 cctv9 Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "cctv1" 3) (integer) 1 1) "subscribe" 2) "cctv9" 3) (integer) 2 1) "message" 2) "cctv1" 3) "xinwenlianbo" 1) "message" 2) "cctv9" 3) "xiongchumo"

發送端

127.0.0.1:6379> publish cctv1 xinwenlianbo (integer) 1 127.0.0.1:6379> publish cctv9 xiongchumo (integer) 1

13、主從復制的配置

13.1、修改配置文件

bind 0.0.0.0

13.2、配置主從復制

小弟可以選擇誰是大哥,但大哥沒有權利去選擇小弟

slaveof 81.70.1.65 6379 127.0.0.1:6379> info replication # Replication role:master connected_slaves:0 master_replid:30d46f6b4ef072f1feff943f6ed9cba15bdf6546 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:0 second_repl_offset:-1 repl_backlog_active:0 repl_backlog_size:1048576 repl_backlog_first_byte_offset:0 repl_backlog_histlen:0 127.0.0.1:6379> slaveof 81.70.1.65 6379 OK 127.0.0.1:6379> info replication # Replication role:slave master_host:81.70.1.65 master_port:6379 master_link_status:up master_last_io_seconds_ago:4 master_sync_in_progress:0 slave_repl_offset:1932 slave_priority:100 slave_read_only:1 connected_slaves:0 master_replid:2357d52fcf39762c8d1ce3005b3e435e8efe1a69 master_replid2:0000000000000000000000000000000000000000 master_repl_offset:1932 second_repl_offset:-1 repl_backlog_active:1 repl_backlog_size:1048576 repl_backlog_first_byte_offset:1919 repl_backlog_histlen:14

13.3、數據同步問題

只要跟隨后,數據立即同步(不論是跟隨前的數據還是跟隨后的數據都會同步)

13.4、讀寫問題

跟隨后,主機負責寫,從機負責讀(從機無法寫數據)

13.5、主從問題

  • 主機關閉,從機仍是從機(會顯示主機已經掉線,master_link_status:down)
  • 主機再次啟動后從,機仍是從機(會顯示主機已經上線,master_link_status:up)
  • 從機關閉后,對于主機而言僅僅是少了一個從機
  • 從機再次重啟,身份轉變為master,不在在原來的集群,需重新配置

13.6、主從復制原理

  • 全量復制:Slave初始化階段,這時Slave需要將Master上的所有數據都復制一份slave接收到數據 文件后,存盤,并加載到內存中;(步驟1234)
  • 增量復制:Slave初始化后,開始正常工作時主服務器發生的寫操作同步到從服務器的過程;(步驟56)
  • Redis主從同步策略:主從剛剛連接的時候,進行全量同步;全同步結束后,進行增量同步
  • 如果有需要,slave 在任何時候都可以發起全量同步
  • redis 策略是,無論如何,首先會嘗試進行增量同步,如不成功,要求從機進行全量同步

13.7、繼承

一個主機理論上可以多個從機,但是這樣的話,這個主機會很累,可以使用java面向對象繼承中的傳遞性來解決這個問題,減輕主機的負擔

13.8、重選主機

當1個主機掛掉了,從2個從機中再次選1個主機,1為master,2和3為slave,當1掛掉后,2篡權為master,3跟2

slaveof no one

13.9、哨兵模式

自動版重選主機

有個哨兵一直在巡邏,突然發現!!!!!老大掛了,小弟們會自動投票,從眾小弟中選出新的老大

cp /usr/local/redis-5.0.4/sentinel.conf sentinel.conf

修改配置項(僅在主機配置即可)

daemonize yes # 服務器名 服務器ip sentinel monitor redis3 101.34.116.9 6379 1

啟動哨兵

[root@VM-16-14-centos bin]# redis-sentinel sentinel.conf 24628:X 01 Aug 2021 23:34:12.366 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 24628:X 01 Aug 2021 23:34:12.366 # Redis version=5.0.4, bits=64, commit=00000000, modified=0, pid=24628, just started 24628:X 01 Aug 2021 23:34:12.366 # Configuration loaded

自己斷掉主redis,查看從redis的狀態,自動轉為master表示成功

主機重新啟動后,哨兵發現主機連接后,主機會變成小弟,重新加入集群

缺點

  • 所有的寫操作都是在master上完成的,然后再同步到slave上,兩臺機器之間通信會有延遲
  • 當系統很繁忙的時候,延遲問題會加重
  • slave機器數量增加,問題也會加重

13.10、多哨兵模式

待補

14、Redis.conf詳細配置

# 注意單位: 當需要配置內存大小時, 可能需要指定像1k,4M,5GB,等常見格式 # # 1k => 1000 bytes # 1kb => 1024 bytes # 1m => 1000000 bytes # 1mb => 1024*1024 bytes # 1g => 1000000000 bytes # 1gb => 1024*1024*1024 bytes # # redis是對單位大小寫不敏感的 1GB 1Gb 1gB 是相同的 ################################## INCLUDES 包含文件相關 ################################### # 可以在這里包含一個或多個其他的配置文件,如果你有一個適用于所有Redis服務器的標準配置模板 # 但也需要一些每個服務器自定義的設置,這個功能將很有用。被包含的配置文件也可以包含其他配置文件 # # 注意“inclue”選項不能被admin或Redis哨兵的"CONFIG REWRITE"命令重寫 # 因為Redis總是使用最后解析的配置行最為配置指令的值, 你最好在這個文件的開頭配置includes來避免它在運行時重寫配置 # 如果相反你想用includes的配置覆蓋原來的配置,你最好在該文件的最后使用include # # include /path/to/local.conf # include /path/to/other.conf ################################ GENERAL 綜合配置 ##################################### # 默認Rdis不會作為守護進程運行。如果需要的話配置成'yes' # 注意配置成守護進程后Redis會將進程號寫入文件/var/run/redis.pid daemonize no # 當以守護進程方式運行時,默認Redis會把進程ID寫到 /var/run/redis.pid,你可以在這里修改路徑 pidfile /var/run/redis.pid # 接受連接的特定端口,默認是6379 # 如果端口設置為0,Redis就不會監聽TCP套接字。 port 6379 # TCP listen backlog # server在與客戶端建立tcp連接的過程中,SYN隊列的大小 # 在高并發環境下你需要一個高backlog值來避免慢客戶端連接問題。注意Linux內核默默地將這個值減小 # 到/proc/sys/net/core/somaxconn的值,所以需要確認增大somaxconn和tcp_max_syn_backlog # 兩個值來達到想要的效果 tcp-backlog 511 # 默認Redis監聽服務器上所有可用網絡接口的連接。可以用"bind"配置指令跟一個或多個ip地址來實現 # 監聽一個或多個網絡接口 # # 示例: # bind 192.168.1.100 10.0.0.1 # bind 127.0.0.1 # 指定用來監聽Unix套套接字的路徑。沒有默認值, 所以在沒有指定的情況下Redis不會監聽Unix套接字 # # unixsocket /tmp/redis.sock # unixsocketperm 755 # 一個客戶端空閑多少秒后關閉連接(0代表禁用,永不關閉) timeout 0 # TCP keepalive. # # 如果非零,則設置SO_KEEPALIVE選項來向空閑連接的客戶端發送ACK,由于以下兩個原因這是很有用的: # # 1)能夠檢測無響應的對端 # 2)讓該連接中間的網絡設備知道這個連接還存活 # # 在Linux上,這個指定的值(單位:秒)就是發送ACK的時間間隔。 # 注意:要關閉這個連接需要兩倍的這個時間值。 # 在其他內核上這個時間間隔由內核配置決定 # # 這個選項的一個合理值是60秒 tcp-keepalive 0 # 指定服務器調試等級 # 可能值: # debug (大量信息,對開發/測試有用) # verbose (很多精簡的有用信息,但是不像debug等級那么多) # notice (適量的信息,基本上是你生產環境中需要的) # warning (只有很重要/嚴重的信息會記錄下來) loglevel notice # 指明日志文件名。也可以使用"stdout"來強制讓Redis把日志信息寫到標準輸出上。 # 注意:如果Redis以守護進程方式運行,而設置日志顯示到標準輸出的話,日志會發送到/dev/null logfile "" # 要使用系統日志記錄器,只要設置 "syslog-enabled" 為 "yes" 就可以了。 # 然后根據需要設置其他一些syslog參數就可以了。 # syslog-enabled no # 指明syslog身份 # syslog-ident redis # 指明syslog的設備。必須是user或LOCAL0 ~ LOCAL7之一。 # syslog-facility local0 # 設置數據庫個數。默認數據庫是 DB 0, # 可以通過select <dbid> (0 <= dbid <= 'databases' - 1 )來為每個連接使用不同的數據庫 databases 16 ################################ SNAPSHOTTING 快照,持久化操作配置 ################################ # 把數據庫存到磁盤上: # # save <seconds> <changes> # # 會在指定秒數和數據變化次數之后把數據庫寫到磁盤上。 # # 下面的例子將會進行把數據寫入磁盤的操作: # 900秒(15分鐘)之后,且至少1次變更 # 300秒(5分鐘)之后,且至少10次變更 # 60秒之后,且至少10000次變更 # # 注意:你要想不寫磁盤的話就把所有 "save" 設置注釋掉就行了。 # # 通過添加一條帶空字符串參數的save指令也能移除之前所有配置的save指令 # 像下面的例子: # save "" save 900 1 save 300 10 save 60 10000 # 默認如果開啟RDB快照(至少一條save指令)并且最新的后臺保存失敗,Redis將會停止接受寫操作 # 這將使用戶知道數據沒有正確的持久化到硬盤,否則可能沒人注意到并且造成一些災難。 # # 如果后臺保存進程能重新開始工作,Redis將自動允許寫操作 # # 然而如果你已經部署了適當的Redis服務器和持久化的監控,你可能想關掉這個功能以便于即使是 # 硬盤,權限等出問題了Redis也能夠像平時一樣正常工作, stop-writes-on-bgsave-error yes # 當導出到 .rdb 數據庫時是否用LZF壓縮字符串對象? # 默認設置為 "yes",因為幾乎在任何情況下它都是不錯的。 # 如果你想節省CPU的話你可以把這個設置為 "no",但是如果你有可壓縮的key和value的話, # 那數據文件就會更大了。 rdbcompression yes # 因為版本5的RDB有一個CRC64算法的校驗和放在了文件的最后。這將使文件格式更加可靠但在 # 生產和加載RDB文件時,這有一個性能消耗(大約10%),所以你可以關掉它來獲取最好的性能。 # # 生成的關閉校驗的RDB文件有一個0的校驗和,它將告訴加載代碼跳過檢查 rdbchecksum yes # 持久化數據庫的文件名 dbfilename dump.rdb # 工作目錄 # # 數據庫會寫到這個目錄下,文件名就是上面的 "dbfilename" 的值。 # # 累加文件也放這里。 # # 注意你這里指定的必須是目錄,不是文件名。 dir ./ ################################# REPLICATION 主從復制的配置 ################################# # 主從同步。通過 slaveof 指令來實現Redis實例的備份。 # 注意,這里是本地從遠端復制數據。也就是說,本地可以有不同的數據庫文件、綁定不同的IP、監聽 # 不同的端口。 # # slaveof <masterip> <masterport> # 如果master設置了密碼保護(通過 "requirepass" 選項來配置),那么slave在開始同步之前必須 # 進行身份驗證,否則它的同步請求會被拒絕。 # # masterauth <master-password> # 當一個slave失去和master的連接,或者同步正在進行中,slave的行為有兩種可能: # # 1) 如果 slave-serve-stale-data 設置為 "yes" (默認值),slave會繼續響應客戶端請求, # 可能是正常數據,也可能是還沒獲得值的空數據。 # 2) 如果 slave-serve-stale-data 設置為 "no",slave會回復"正在從master同步 # (SYNC with master in progress)"來處理各種請求,除了 INFO 和 SLAVEOF 命令。 # slave-serve-stale-data yes # 你可以配置salve實例是否接受寫操作。可寫的slave實例可能對存儲臨時數據比較有用(因為寫入 salve # 的數據在同master同步之后將很容被刪除),但是如果客戶端由于配置錯誤在寫入時也可能產生一些問題。 # # 從Redis2.6默認所有的slave為只讀 # # 注意:只讀的slave不是為了暴露給互聯網上不可信的客戶端而設計的。它只是一個防止實例誤用的保護層。 # 一個只讀的slave支持所有的管理命令比如config,debug等。為了限制你可以用'renamecommand'來 # 隱藏所有的管理和危險命令來增強只讀slave的安全性 slave-read-only yes # slave根據指定的時間間隔向master發送ping請求。 # 時間間隔可以通過 repl_ping_slave_period 來設置。 # 默認10秒。 # # repl-ping-slave-period 10 # 以下選項設置同步的超時時間 # # 1)slave在與master SYNC期間有大量數據傳輸,造成超時 # 2)在slave角度,master超時,包括數據、ping等 # 3)在master角度,slave超時,當master發送REPLCONF ACK pings # # 確保這個值大于指定的repl-ping-slave-period,否則在主從間流量不高時每次都會檢測到超時 # # repl-timeout 60 # 是否在slave套接字發送SYNC之后禁用 TCP_NODELAY ? # # 如果你選擇“yes”Redis將使用更少的TCP包和帶寬來向slaves發送數據。但是這將使數據傳輸到 slave # 上有延遲,Linux內核的默認配置會達到40毫秒 # # 如果你選擇了 "no" 數據傳輸到salve的延遲將會減少但要使用更多的帶寬 # # 默認我們會為低延遲做優化,但高流量情況或主從之間的跳數過多時,把這個選項設置為“yes” # 是個不錯的選擇。 repl-disable-tcp-nodelay no # 設置數據備份的backlog大小。backlog是一個slave在一段時間內斷開連接時記錄salve數據的緩 沖, # 所以一個slave在重新連接時,不必要全量的同步,而是一個增量同步就足夠了,將在斷開連接的這段 # 時間內slave丟失的部分數據傳送給它。 # # 同步的backlog越大,slave能夠進行增量同步并且允許斷開連接的時間就越長。 # # backlog只分配一次并且至少需要一個slave連接 # # repl-backlog-size 1mb # 當master在一段時間內不再與任何slave連接,backlog將會釋放。以下選項配置了從最后一個 # slave斷開開始計時多少秒后,backlog緩沖將會釋放。 # # 0表示永不釋放backlog # # repl-backlog-ttl 3600 # slave的優先級是一個整數展示在Redis的Info輸出中。如果master不再正常工作了,哨兵將用它來 # 選擇一個slave提升=升為master。 # # 優先級數字小的salve會優先考慮提升為master,所以例如有三個slave優先級分別為10,100,25, # 哨兵將挑選優先級最小數字為10的slave。 # # 0作為一個特殊的優先級,標識這個slave不能作為master,所以一個優先級為0的slave永遠不會被 # 哨兵挑選提升為master # # 默認優先級為100 slave-priority 100 # 如果master少于N個延時小于等于M秒的已連接slave,就可以停止接收寫操作。 # # N個slave需要是“oneline”狀態 # # 延時是以秒為單位,并且必須小于等于指定值,是從最后一個從slave接收到的ping(通常每秒發送) # 開始計數。 # # This option does not GUARANTEES that N replicas will accept the write, but # will limit the window of exposure for lost writes in case not enough slaves # are available, to the specified number of seconds. # # 例如至少需要3個延時小于等于10秒的slave用下面的指令: # # min-slaves-to-write 3 # min-slaves-max-lag 10 # # 兩者之一設置為0將禁用這個功能。 # # 默認 min-slaves-to-write 值是0(該功能禁用)并且 min-slaves-max-lag 值是10。 ################################## SECURITY 安全相關配置 ################################### # 要求客戶端在處理任何命令時都要驗證身份和密碼。 # 這個功能在有你不信任的其它客戶端能夠訪問redis服務器的環境里非常有用。 # # 為了向后兼容的話這段應該注釋掉。而且大多數人不需要身份驗證(例如:它們運行在自己的服務器上) # # 警告:因為Redis太快了,所以外面的人可以嘗試每秒150k的密碼來試圖破解密碼。這意味著你需要 # 一個高強度的密碼,否則破解太容易了。 # # requirepass foobared # 命令重命名 # # 在共享環境下,可以為危險命令改變名字。比如,你可以為 CONFIG 改個其他不太容易猜到的名字, # 這樣內部的工具仍然可以使用,而普通的客戶端將不行。 # # 例如: # # rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 # # 也可以通過改名為空字符串來完全禁用一個命令 # # rename-command CONFIG "" # # 請注意:改變命令名字被記錄到AOF文件或被傳送到從服務器可能產生問題。 ################################### LIMITS 范圍配置 #################################### # 設置最多同時連接的客戶端數量。默認這個限制是10000個客戶端,然而如果Redis服務器不能配置 # 處理文件的限制數來滿足指定的值,那么最大的客戶端連接數就被設置成當前文件限制數減32(因 # 為Redis服務器保留了一些文件描述符作為內部使用) # # 一旦達到這個限制,Redis會關閉所有新連接并發送錯誤'max number of clients reached' # # maxclients 10000 # 不要用比設置的上限更多的內存。一旦內存使用達到上限,Redis會根據選定的回收策略(參見: # maxmemmory-policy)刪除key # # 如果因為刪除策略Redis無法刪除key,或者策略設置為 "noeviction",Redis會回復需要更 # 多內存的錯誤信息給命令。例如,SET,LPUSH等等,但是會繼續響應像Get這樣的只讀命令。 # # 在使用Redis作為LRU緩存,或者為實例設置了硬性內存限制的時候(使用 "noeviction" 策略) # 的時候,這個選項通常事很有用的。 # # 警告:當有多個slave連上達到內存上限的實例時,master為同步slave的輸出緩沖區所需 # 內存不計算在使用內存中。這樣當驅逐key時,就不會因網絡問題 / 重新同步事件觸發驅逐key # 的循環,反過來slaves的輸出緩沖區充滿了key被驅逐的DEL命令,這將觸發刪除更多的key, # 直到這個數據庫完全被清空為止 # # 總之...如果你需要附加多個slave,建議你設置一個稍小maxmemory限制,這樣系統就會有空閑 # 的內存作為slave的輸出緩存區(但是如果最大內存策略設置為"noeviction"的話就沒必要了) # # maxmemory <bytes> # 最大內存策略:如果達到內存限制了,Redis如何選擇刪除key。你可以在下面五個行為里選: # # volatile-lru -> 根據LRU算法生成的過期時間來刪除。 # allkeys-lru -> 根據LRU算法刪除任何key。 # volatile-random -> 根據過期設置來隨機刪除key。 # allkeys->random -> 無差別隨機刪。 # volatile-ttl -> 根據最近過期時間來刪除(輔以TTL) # noeviction -> 誰也不刪,直接在寫操作時返回錯誤。 # # 注意:對所有策略來說,如果Redis找不到合適的可以刪除的key都會在寫操作時返回一個錯誤。 # # 目前為止涉及的命令:set setnx setex append # incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd # sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby # zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby # getset mset msetnx exec sort # # 默認值如下: # # maxmemory-policy volatile-lru # LRU和最小TTL算法的實現都不是很精確,但是很接近(為了省內存),所以你可以用樣本量做檢測。 # 例如:默認Redis會檢查3個key然后取最舊的那個,你可以通過下面的配置指令來設置樣本的個數。 # # maxmemory-samples 3 ############################## APPEND ONLY MODE AOF模式配置 ############################### # 默認情況下,Redis是異步的把數據導出到磁盤上。這種模式在很多應用里已經足夠好,但Redis進程 # 出問題或斷電時可能造成一段時間的寫操作丟失(這取決于配置的save指令)。 # # AOF是一種提供了更可靠的替代持久化模式,例如使用默認的數據寫入文件策略(參見后面的配置) # 在遇到像服務器斷電或單寫情況下Redis自身進程出問題但操作系統仍正常運行等突發事件時,Redis # 能只丟失1秒的寫操作。 # # AOF和RDB持久化能同時啟動并且不會有問題。 # 如果AOF開啟,那么在啟動時Redis將加載AOF文件,它更能保證數據的可靠性。 # # 請查看 http://redis.io/topics/persistence 來獲取更多信息. appendonly no # 純累加文件名字(默認:"appendonly.aof") appendfilename "appendonly.aof" # fsync() 系統調用告訴操作系統把數據寫到磁盤上,而不是等更多的數據進入輸出緩沖區。 # 有些操作系統會真的把數據馬上刷到磁盤上;有些則會盡快去嘗試這么做。 # # Redis支持三種不同的模式: # # no:不要立刻刷,只有在操作系統需要刷的時候再刷。比較快。 # always:每次寫操作都立刻寫入到aof文件。慢,但是最安全。 # everysec:每秒寫一次。折中方案。 # # 默認的 "everysec" 通常來說能在速度和數據安全性之間取得比較好的平衡。根據你的理解來 # 決定,如果你能放寬該配置為"no" 來獲取更好的性能(但如果你能忍受一些數據丟失,可以考慮使用 # 默認的快照持久化模式),或者相反,用“always”會比較慢但比everysec要更安全。 # # 請查看下面的文章來獲取更多的細節 # http://antirez.com/post/redis-persistence-demystified.html # # 如果不能確定,就用 "everysec" # appendfsync always appendfsync everysec # appendfsync no # 如果AOF的同步策略設置成 "always" 或者 "everysec",并且后臺的存儲進程(后臺存儲或寫入AOF # 日志)會產生很多磁盤I/O開銷。某些Linux的配置下會使Redis因為 fsync()系統調用而阻塞很久。 # 注意,目前對這個情況還沒有完美修正,甚至不同線程的 fsync() 會阻塞我們同步的write(2)調用。 # # 為了緩解這個問題,可以用下面這個選項。它可以在 BGSAVE 或 BGREWRITEAOF 處理時阻止fsync()。 # # 這就意味著如果有子進程在進行保存操作,那么Redis就處于"不可同步"的狀態。 # 這實際上是說,在最差的情況下可能會丟掉30秒鐘的日志數據。(默認Linux設定) # # 如果把這個設置成"yes"帶來了延遲問題,就保持"no",這是保存持久數據的最安全的方式。 no-appendfsync-on-rewrite no # 自動重寫AOF文件 # 如果AOF日志文件增大到指定百分比,Redis能夠通過 BGREWRITEAOF 自動重寫AOF日志文件。 # # 工作原理:Redis記住上次重寫時AOF文件的大小(如果重啟后還沒有寫操作,就直接用啟動時的AOF大 小) # # 這個基準大小和當前大小做比較。如果當前大小超過指定比例,就會觸發重寫操作。你還需要指定被重寫 # 日志的最小尺寸,這樣避免了達到指定百分比但尺寸仍然很小的情況還要重寫。 # # 指定百分比為0會禁用AOF自動重寫特性。 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb ################################ LUA SCRIPTING ############################### # 設置lua腳本的最大運行時間,單位為毫秒,redis會記個log,然后返回error。當一個腳本超過了最大時限。 # 只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一個可以殺沒有調write命令的東西。要是已經調用了write,只能用第二個命令殺。 lua-time-limit 5000 ################################## SLOW LOG ################################### # 是redis用于記錄慢查詢執行時間的日志系統。由于slowlog只保存在內存中,因此slowlog的效率很高,完全不用擔心會影響到redis的性能。 # 只有query執行時間大于slowlog-log-slower-than的才會定義成慢查詢,才會被slowlog進行記錄。 # 單位是微妙 slowlog-log-slower-than 10000 # slowlog-max-len表示慢查詢最大的條數 slowlog-max-len 128 ############################ EVENT NOTIFICATION ############################## # 這個功能可以讓客戶端通過訂閱給定的頻道或者模式,來獲知數據庫中鍵的變化,以及數據庫中命令的執行情況,所以在默認配置下,該功能處于關閉狀態。 # notify-keyspace-events 的參數可以是以下字符的任意組合,它指定了服務器該發送哪些類型的通知: # K 鍵空間通知,所有通知以 __keyspace@__ 為前綴 # E 鍵事件通知,所有通知以 __keyevent@__ 為前綴 # g DEL 、 EXPIRE 、 RENAME 等類型無關的通用命令的通知 # $ 字符串命令的通知 # l 列表命令的通知 # s 集合命令的通知 # h 哈希命令的通知 # z 有序集合命令的通知 # x 過期事件:每當有過期鍵被刪除時發送 # e 驅逐(evict)事件:每當有鍵因為 maxmemory 政策而被刪除時發送 # A 參數 g$lshzxe 的別名 # 輸入的參數中至少要有一個 K 或者 E,否則的話,不管其余的參數是什么,都不會有任何 通知被分發。詳細使用可以參考http://redis.io/topics/notifications notify-keyspace-events "" ############################### ADVANCED CONFIG ############################### # 單位字節:數據量小于等于hash-max-ziplist-entries的用ziplist,大于hash-max-ziplistentries用hash hash-max-ziplist-entries 512 # value大小小于等于hash-max-ziplist-value的用ziplist,大于hash-max-ziplist-value用hash。 hash-max-ziplist-value 64 # 數據量小于等于list-max-ziplist-entries用ziplist(壓縮列表),大于list-max-ziplistentries用list。 list-max-ziplist-entries 512 # value大小小于等于list-max-ziplist-value的用ziplist,大于list-max-ziplist-value用list。 list-max-ziplist-value 64 # 數據量小于等于set-max-intset-entries用iniset,大于set-max-intset-entries用set。 set-max-intset-entries 512 # 數據量小于等于zset-max-ziplist-entries用ziplist,大于zset-max-ziplist-entries用zset。 zset-max-ziplist-entries 128 # value大小小于等于zset-max-ziplist-value用ziplist,大于zset-max-ziplist-value用zset。 zset-max-ziplist-value 64 # 基數統計的算法 HyperLogLog 鍵只需要花費 12 KB 內存,就可以計算接近 2^64 個不同元素的基數 # 設置HyeperLogLog的字節數限制,這個值通常在0~15000之間,默認為3000,基本不超過16000。 # value大小小于等于hll-sparse-max-bytes使用稀疏數據結構(sparse),大于hll-sparse-maxbytes使用稠密的數據結構(dense)。 # 一個比16000大的value是幾乎沒用的,建議的value大概為3000。如果對CPU要求不高,對空間要求較高的,建議設置到10000左右。 hll-sparse-max-bytes 3000 # 重置hash。 Redis將在每100毫秒時使用1毫秒的CPU時間來對redis的hash表進行重新hash,可以降低內存的使用。 # 當你的使用場景中,有非常嚴格的實時性需要,不能夠接受Redis時不時的對請求有2毫秒的延遲的話,把這項配置為no。 # 如果沒有這么嚴格的實時性要求,可以設置為yes,以便能夠盡可能快的釋放內存。 activerehashing yes # 對于Redis服務器的輸出(也就是命令的返回值)來說,其大小通常是不可控制的。有可能一個簡單的命令,能夠產生體積龐大的返回數據。 # 另外也有可能因為執行了太多命令,導致產生返回數據的速率超過了往客戶端發送的速率,這是也會導致服務器堆積大量消息, # 從而導致輸出緩沖區越來越大,占用過多內存,甚至導致系統崩潰。 # 用于強制斷開出于某些原因而無法以足夠快的速度從服務器讀取數據的客戶端的連接。 # 對于normal client,包括monitor。第一個0表示取消hard limit,第二個0和第三個0表示取消 # soft limit,normal client默認取消限制,因為如果沒有尋問,他們是不會接收數據的。 client-output-buffer-limit normal 0 0 0 #對于slave client和MONITER client,如果client-output-buffer一旦超過256mb,又或者超過64mb持續60秒,那么服務器就會立即斷開客戶端連接。 client-output-buffer-limit slave 256mb 64mb 60 #對于pubsub client,如果client-output-buffer一旦超過32mb,又或者超過8mb持續60秒,那么服務器就會立即斷開客戶端連接。 client-output-buffer-limit pubsub 32mb 8mb 60 # redis執行任務的頻率 hz 10 # aof rewrite過程中,是否采取增量"文件同步"策略,默認為"yes",而且必須為yes. # rewrite過程中,每32M數據進行一次文件同步,這樣可以減少"aof大文件"寫入對磁盤的操作次數. aof-rewrite-incremental-fsync yes

15、Jedis

15.1、redis服務器準備

  • 服務器配置安全組
  • redis允許所有ip訪問(注釋bind 127.0.0.1)
  • 關閉保護模式(protected-mode no)

附上linux防火墻命令

  • systemctl start firewalld:啟動
  • systemctl status firewalld:查看狀態
  • systemctl disable firewalld:禁止開機啟動
  • systemctl stop firewalld:停止運行
  • firewall-cmd --zone=public --list-ports:查看所有打開的端口
  • firewall-cmd --reload更新防火墻規則
  • 開啟端口:firewall-cmd --zone=public --add-port=80/tcp --permanent (–permanent永久生效,沒有此參數重啟后失效)

15.2、導入依賴

<dependencies><!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency> </dependencies>

15.3、測試

public class RedisTest {@Testpublic void ping(){Jedis jedis=new Jedis("106.54.85.216",6379);System.out.println(jedis.ping());} }

15.4、API

同linux操作命令,示例待補

15.5、事務

@Test public void transaction(){Jedis jedis=new Jedis("106.54.85.216",6379);jedis.set("in","5000");jedis.set("out","1000");try {Transaction multi = jedis.multi();multi.decrBy("in",500);multi.incrBy("out",500);multi.exec();} catch (Exception e) {e.printStackTrace();}System.out.println(jedis.get("in"));System.out.println(jedis.get("out")); }

16、JedisPool

16.1、導入依賴

<dependencies><!-- https://mvnrepository.com/artifact/redis.clients/jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.2.0</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13</version><scope>test</scope></dependency><!-- https://mvnrepository.com/artifact/commons-pool/commons-pool --><dependency><groupId>commons-pool</groupId><artifactId>commons-pool</artifactId><version>1.6</version></dependency> </dependencies>

16.2、JedisPoolUtil

public class JedisPoolUtil {private volatile static JedisPool jedisPool=null;private static JedisPool createJedisPool(){if (jedisPool==null){synchronized (JedisPoolUtil.class){JedisPoolConfig jedisPoolConfig=new JedisPoolConfig();// 連接池中的最大連接數jedisPoolConfig.setMaxTotal(100);// 連接池允許的最大空閑連接數jedisPoolConfig.setMaxIdle(30);// 當連接池連接用盡后,調用者的最大等待時間(單位為毫秒)jedisPoolConfig.setMaxWaitMillis(30*1000);// 向連接池借用連接時是否做連接有效性檢測(業務量很大時候建議設置為false,減少一次ping的開銷)jedisPoolConfig.setTestOnBorrow(true);jedisPool=new JedisPool(jedisPoolConfig,"106.54.85.216",6379);}}return jedisPool;}public static Jedis createJedis(){if (jedisPool==null){return createJedisPool().getResource();}return jedisPool.getResource();} }

總結

以上是生活随笔為你收集整理的Java分布式篇4——Redis的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。