深入分析Redis

深入分析Redis

推薦(免費):redis

1 redis簡介

什么是Redis
Redis是完全開源免費的,遵守BSD協議,是?個?性能(nosql)的key-value數據庫。Redis是?個開源的使?ANSI C語?編寫、?持?絡、可基于內存亦可持久化的?志型、Key-Value數據庫,并提供多種語?的API。

BSD是“Berkeley Software Distribution”的縮寫,意思是“伯克利軟件發?版”。 BSD開源協議是?個給與使?者很??由的協議??梢?由的使?,修改源代碼,也可以將修改后的代碼作 為開源或者專有軟件再發布。 BSD由于允許使?者修改或者重新發布代碼,也允許使?或在BSD代碼上開發商業軟件發布和銷售,因此是 對商業集成很友好的協議。 linux:Ubuntu Redhat Centos

Nosql:

Nosql, 泛指?關系型數據庫,Nosql即Not-only SQL,他作為關系型數據庫的良好補充。隨著互聯?的 興起,?關系型數據庫現在成為了?個極其熱?的新領域,?關系型數據庫產品的發展?常迅速

2 Redis安裝

2.1 安裝前準備

Redis官?

官??站:http://redis.io
中?官?:http://redis.cn
官??站下載:http://redis.io/download

Redis 安裝

Linux
Redis是C語?開發,安裝Redis需要先將官?下載的源碼進?編譯,編譯依賴GCC環境,如果沒有GCC環境,需要安裝GCC

$ wget http://download.redis.io/releases/redis-5.0.5.tar.gz $ tar xzf redis-5.0.5.tar.gz $ cd redis-5.0.5$ make

windows
深入分析Redis

直接解壓即可
建議redis安裝的?錄增加到環境變量

2.2 Redis的啟動

Linux啟動Redis服務端

進?對應的安裝?錄

cd /usr/local/redis

執?命令

./bin/redis-server

深入分析Redis

Linux啟動Redis客戶端

./bin/redis-cli

Windows啟動Redis服務端

進?對應的安裝?錄,打開命令窗?
執?命令

redis-server redis.window.conf

深入分析Redis

Windows啟動Redis客戶端

進?對應的安裝?錄,打開命令窗?
執?命令

redis-cli

客戶端啟動成功之后的圖:
深入分析Redis

3 Redis核?配置?件Redis.conf

*1. Redis 默認不是以守護進程的?式運?,可以通過該配置項修改,使?yes啟動守護進程  daemonize no2. 當客戶端閑置多?時間后關閉連接(單位是秒)  timeout 300*3. 指定Redis監聽端?,默認端?為6379,作者在??博?中解釋了為什么選?6379作為默認端?,因 為6379在?機按鍵上MERZ對應的號碼,?MERZ取?意?利歌?Alessia Merz的名字  port 6379*4. 綁定的主機地址  bind 127.0.0.1  5. 指定?志記錄級別,Redis共?持四個級別:debug、verbose、notice、warning  loglevel verbose6. 數據庫數量(單機環境下),默認數據庫為0,可以使?select <dbid>命令在連接上指定數據庫id  databases 16// ?常重要*7. RDB 持久化策略,指定在多?時間內,有多少次更新操作,就將數據同步到數據?件,可以多個條件 配合  save <seconds> <changes>  Redis默認配置?件提供了三個條件  save 900 1  save 300 10  save 60 100008. 持久化?件名  dbfilename dump.rdb*9. 指定存儲?本地數據庫時是否壓縮數據,默認為yes,Redis采?LZF(壓縮算法)壓縮,如果為了節 省CPU時間,可以關閉該選項,但會導致數據庫?件變得巨?  rdbcompression yes*10. 設置Redis連接密碼,如果配置了連接密碼,客戶端在連接Redis的時候需要通過 AUTH<password> 命令提供密碼,默認關閉  requirepass foobared// AOF 配置*11. 指定是否在每次操作后進??志記錄,Redis在默認情況下是關閉的  appendonly no*12. AOF?件的名字  appendfilename "appendonly.aof"*13. aof策略,分為三種,always表示每次操作都會記錄?志,everysec表示每秒記錄?次?志,no表 示不記錄?志  # appendfsync always  appendfsync everysec  # appendfsync no

Redis持久化總結:

RDB:是Redis默認的持久化機制。RDB相當于照快照,保存的是?種狀態。??GB的數據 ——> ?KB
的快照

快照是默認的持久化?式,這種?式是就是將內存中數據以快照的?式寫?到?進制?件中,默認的?件名為dump.rdb。

優點:快照保存數據極快、還原數據極快
適?于容災備份

缺點:?內存機器不適合使?,RDB機制符合要求就會照快照,可能會丟失數據

快照條件:

1、服務器正常關閉時 ./bin/redis-cli shutdown

2、key滿??定條件,會進?快照

AOF:由于快照?式是在?定時間間隔內做?次的,那么如果redis意外down掉的話,就會丟失最后?次快照后的所有修改。如果應?要求不能丟失任何修改的話,可以采取aof持久化?式。

Append-only file:aof ?快照?式有更好的持久化性,是由于在使?aof持久化?式時,redis會將每?個收到的寫命令都通過write函數追加到?件中(默認appendonly.aof)。當redis重啟時會通過執??件中保存的寫命令來在內存中重建整個數據庫的內容。

有三種?式如下:(默認是每秒?次)

appendonly yes 啟?aof持久化?式
appendsync always 收到寫命令就?即寫?磁盤,最慢,但是保證完全的持久化
appendsync 每秒鐘寫?磁盤?次,在性能和持久化??做了很好的折中
appendsync no 完全依賴os,性能最好,持久化沒有保證

4 Redis常?數據類型以及應?場景

Redis?持五種數據類型:String字符串),hash(哈希),list(列表),set(集合)以及 zset(sorted set:有序集合) 等

4.1 String

string是Redis最基本的類型,?個key對應?個value,?個鍵最?能存儲512MB。

string類型是?進制安全的。意思是Redis的string可以包含任何數據。?如jpg圖?或者序列化對象。

?進制安全是指,在傳輸數據時,保證?進制數據的信息安全,也就是不被篡改、破譯等,如果有被攻
擊,能夠及時檢測出來

跟之前的map ?常類似。Value是字符串。

SET key value GET key INCR 可以對應的key的數值(整型的數值)加?( 原?操作)INCRBY 給數值加上?個步? SETEX expire 過期 SETNX not exist key不存在的時候再去賦值

應?場景:很常?的場景?于統計?站訪問數量 pv(Page view),當前在線?數等。incr命令(++操 作)

4.2 List

Redis的列表允許?戶從序列的兩端推?或者彈出元素,列表由多個字符串值組成的有序可重復的序列,是鏈表結構,所以向列表兩端添加元素的時間復雜度為o(1),獲取越接近兩端的元素速度就越快。這意味著即使是?個有?千萬個元素的列表,獲取頭部或尾部的10條記錄也是極快的。List中可以包含的最?元素數量是4294967295。

操作命令: LPUSH 后?的元素放在棧頂 LPOP 返回第?個元素,并且在列表上刪除該元素 (棧頂) LLEN 返回當前的list列表的?度 LINDEX 返回當前的list的指定index下標的元素。沒有返回nil,0表示棧頂的元素 LINSERT 插?的位置是按照index的順序,Before的話得注意 index的值 LPUSHX 如果list存在,再去push LRANGE 可以?便的查看某個index范圍內的list的值。輸?的index是從0開始,顯示的標號是從1開始的。 LREM 刪除list?的指定的前?個(指定value的)元素 刪除指定位置的元素:沒有 LSET 設置指定的位置的元素的值 (修改) 輸?的index是從0開始,顯示的標號是從1開始的。

應?場景:1.最新消息排?榜。2.消息隊列,以完成多程序之間的消息交換。可以?push操作將任務存
在list中(?產者),然后線程在?pop操作將任務取出進?執?。(消費者)

4.3 Hash (?維表)

Redis中的散列可以看成具有String key和String value的map容器,可以將多個key-value存儲到?個key中。每?個Hash可以存儲4294967295個鍵值對。

HSET HSET key field value 將哈希表 key 中的域 field 的值設為 value 。 如果 key 不存在,?個新的哈希表被創建并進? HSET 操作。 如果域 field 已經存在于哈希表中,舊值將被覆蓋。  HGET 返回哈希表 key 中給定域 field 的值。如果不存在,返回nil  HEXISTS HEXISTS key field 查看哈希表 key 中,給定域 field 是否存在。  HGETALL HGETALL key 返回哈希表 key 中,所有的域和值。 在返回值?,緊跟每個域名(field name)之后是域的值(value),所以返回值的?度是哈希表??的 兩倍。  HKEYS HKEYS key 返回哈希表 key 中的所有值。  HLEN 返回哈希表 key 中值的數量。  HVALS HVALS key 返回哈希表 key 中所有域的值。  HINCRBY HINCRBY key field increment 為哈希表 key 中的域 field 的值加上增量 increment 。 增量也可以為負數,相當于對給定域進?減法操作。 如果 key 不存在,?個新的哈希表被創建并執? HINCRBY 命令。 如果域 field 不存在,那么在執?命令前,域的值被初始化為 0 。 對?個儲存字符串值的域 field 執? HINCRBY 命令將造成?個錯誤。 本操作的值被限制在 64 位(bit)有符號數字表示之內。  HMGET HMGET key field [field ...]返回哈希表 key 中,?個或多個給定域的值。 如果給定的域不存在于哈希表,那么返回?個 nil 值。 因為不存在的 key 被當作?個空哈希表來處理,所以對?個不存在的 key 進? HMGET 操作將 返回?個只帶有 nil 值的表。  HMSET HMSET key field value [field value ...]同時將多個 field-value (域-值)對設置到哈希表 key 中。 此命令會覆蓋哈希表中已存在的域。 如果 key 不存在,?個空哈希表被創建并執? HMSET 操作。  HSETNX HSETNX key field value 將哈希表 key 中的域 field 的值設置為 value ,當且僅當域 field 不存在。 若域 field 已經存在,該操作?效。 如果 key 不存在,?個新哈希表被創建并執? HSETNX 命令。

應?場景:例如存儲、讀取、修改?戶屬性(name,age,pwd等)

4.4 Set(?序集合)

SADD SADD key member [member ...]將?個或多個 member 元素加?到集合 key 當中,已經存在于集合的 member 元素將被忽略。 假如 key 不存在,則創建?個只包含 member 元素作成員的集合。 當 key 不是集合類型時,返回?個錯誤。 SMEMBERS SMEMBERS key 返回集合 key 中的所有成員。 不存在的 key 被視為空集合。 SISMEMBER SISMEMBER key member 判斷 member 元素是否集合 key 的成員。 SCARD SCARD key 返回集合 key 的基數(集合中元素的數量)。 SPOP (彈出并從集合刪除) SPOP key 移除并返回集合中的?個隨機元素。 如果只想獲取?個隨機元素,但不想該元素從集合中被移除的話,可以使? SRANDMEMBER 命 令。 SRANDMEMBER SRANDMEMBER key [count]如果命令執?時,只提供了 key 參數,那么返回集合中的?個隨機元素。 隨機取出 count個元素(不刪除) SINTER SINTER key [key ...]返回?個集合的全部成員,該集合是所有給定集合的交集。 不存在的 key 被視為空集。 SINTERSTORE SINTERSTORE destination key [key ...]這個命令類似于 SINTER 命令,但它將結果保存到 destination 集合,?不是簡單地返回結果 集。 如果 destination 集合已經存在,則將其覆蓋。 SUNION SUNION key [key ...]返回?個集合的全部成員,該集合是所有給定集合的并集。 不存在的 key 被視為空集。 SUNIONSTORE SUNIONSTORE destination key [key ...]這個命令類似于 SUNION 命令,但它將結果保存到 destination 集合,?不是簡單地返回結果 集。 如果 destination 已經存在,則將其覆蓋。 SDIFF SDIFF key [key ...]返回?個集合的全部成員,該集合是所有給定集合之間的差集。 不存在的 key 被視為空集。 SDIFFSTORE SDIFFSTORE destination key [key ...]這個命令的作?和 SDIFF 類似,但它將結果保存到 destination 集合,?不是簡單地返回結果 集。 如果 destination 集合已經存在,則將其覆蓋。 destination 可以是 key 本身。 SMOVE SMOVE source destination member 將 member 元素從 source 集合移動到 destination 集合。SMOVE 是原?性操作。 SREM 刪除 SREM key member [member ...]移除集合 key 中的?個或多個 member 元素,不存在的 member 元素會被忽略。 當 key 不是集合類型,返回?個錯誤。

應?場景:
1.利?交集求共同好友。
2.利?唯?性,可以統計訪問?站的所有獨?IP。
3.好友推薦的時候根據tag求交集,?于某個threshold(臨界值的)就可以推薦。
4.5 SortSet(有序集合)

ZADD ZADD key score member [[score member] [score member] ...]將?個或多個 member 元素及其 score 值加?到有序集 key 當中。  ZCARD ZCARD key 返回有序集 key 的基數。  ZSCORE ZSCORE key member 返回有序集 key 中,成員 member 的 score 值。 如果 member 元素不是有序集 key 的成員,或 key 不存在,返回 nil 。  ZCOUNT (閉區間) ZCOUNT key min max 返回有序集 key 中, score 值在 min 和 max 之間(默認包括 score 值等于 min 或 max )的 成員的數量。 關于參數 min 和 max 的詳細使??法,請參考 ZRANGEBYSCORE 命令。  ZINCRBY ZINCRBY key increment member 為有序集 key 的成員 member 的 score 值加上增量 increment 。  ZRANGE ZRANGE key start stop [WITHSCORES]返回有序集 key 中,指定區間內的成員。 其中成員的位置按 score 值遞增(從?到?)來排序。 具有相同 score 值的成員按字典序(lexicographical order )來排列。  ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]返回有序集 key 中,所有 score 值介于 min 和 max 之間(包括等于 min 或 max )的成員。有 序集成員按 score 值遞增(從?到?)次序排列。 根據指定的分值范圍去查找  ZRANK (排名從0開始) ZRANK key member 返回有序集 key 中成員 member 的排名。其中有序集成員按 score 值遞增(從?到?)順序排 列。  ZREVRANGE ZREVRANGE key start stop [WITHSCORES]返回有序集 key 中,指定區間內的成員。 其中成員的位置按 score 值遞減(從?到?)來排列。 具有相同 score 值的成員按字典序的逆序(reverse lexicographical order)排列。  ZREVRANGEBYSCORE ZREVRANGE key start stop [WITHSCORES]返回有序集 key 中,指定區間內的成員。  ZREVRANK ZREVRANK key member 返回有序集 key 中成員 member 的排名。其中有序集成員按 score 值遞減(從?到?)排序。 排名以 0 為底,也就是說, score 值最?的成員排名為 0 。 使? ZRANK 命令可以獲得成員按 score 值遞增(從?到?)排列的排名。  ZREM ZREM key member [member ...]移除有序集 key 中的?個或多個成員,不存在的成員將被忽略。 當 key 存在但不是有序集類型時,返回?個錯誤。  ZREMRANGEBYRANK ZREMRANGEBYRANK key start stop 移除有序集 key 中,指定排名(rank)區間內的所有成員。 區間分別以下標參數 start 和 stop 指出,包含 start 和 stop 在內。  ZREMRANGEBYSCORE ZREMRANGEBYSCORE key min max 移除有序集 key 中,所有 score 值介于 min 和 max 之間(包括等于 min 或 max )的成員。

應?場景:可以?于?個?型在線游戲的積分排?榜,每當玩家的分數發?變化時,可以執?zadd更新
玩家分數(score),此后在通過zrange獲取?分top ten的?戶信息。

5 Redis的整合(Jedis) Java for Redis

5.1 導包

<dependency>  <groupId>redis.clients</groupId>  <artifactId>jedis</artifactId>  <version>2.9.0</version></dependency>

5.2 配置

@Configurationpublic class RedisConfig {    @Bean  public Jedis jedis(){  Jedis jedis = new Jedis("localhost", 6379);  return jedis;  }}

5.3 使?

// 直接引? @Autowiredprivate Jedis jedis;// 使? 和在命令?客戶端操作是?樣的jedis.set();jedis.get();jedis.hset();jedis.hget();jedis.sadd();...

6 springboot2.x中Redis進?連接(RedisTemplate)

RedisTemplate 簡介,SpringBoot對Redis進?了?層模板化的封裝,?便我們對對象進?操作。底層
在SpringBoot1.x的時候使?的是Jedis,在Springboot2.x后使?的是lettuce。

6.1 導包

<dependency>  <groupId>org.springframework.boot</groupId>  <artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- 序列化 --><dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-core</artifactId>  <version>2.10.0</version></dependency> <dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-databind</artifactId>  <version>2.10.0</version></dependency>

6.2 配置

@Configurationpublic class RedisConfig {   @Bean  public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){  RedisTemplate redisTemplate = new RedisTemplate();  redisTemplate.setConnectionFactory(redisConnectionFactory);    //定制化模板  StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();  redisTemplate.setKeySerializer(stringRedisSerializer);  // 設置value JackSon序列化?式  Jackson2JsonRedisSerializer jsonRedisSerializer = new  Jackson2JsonRedisSerializer(Object.class);    ObjectMapper objectMapper = new ObjectMapper();  // 對于不是基本類型的變量顯示全類名    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  //設置值的屬性可?  objectMapper.setVisibility(PropertyAccessor.ALL,JsonAutoDetect.Visibility.AN Y);  jsonRedisSerializer.setObjectMapper(objectMapper);  redisTemplate.setValueSerializer(jsonRedisSerializer);  return redisTemplate;  }}

6.3 使?

 redisTemplate.opsForValue().set();  redisTemplate.opsForHash().put();  redisTemplate.opsForList().leftPush();  redisTemplate.opsForSet().add();  redisTemplate.opsForZSet().add();

7 Springboot2.x中使?Redisson進?連接

Redisson:Redisson是?個在Redis的基礎上實現的Java駐內存數據?格(In-Memory Data Grid)。它不僅提供了?系列的分布式的Java常?對象,還提供了許多分布式服務。其中包括( BitSet , Set ,
Multimap , SortedSet , Map , List , Queue , BlockingQueue , Deque , BlockingDeque ,Semaphore , Lock , AtomicLong , CountDownLatch , Publish / Subscribe , Bloom Filter ,Remote service , Spring cache , Executor service , Live Object service , Scheduler service ) Redisson提供了使?Redis的最簡單和最便捷的?法。Redisson的宗旨是促進使?者對Redis的關注分離(Separation of Concern),從?讓使?者能夠將精?更集中地放在處理業務邏輯上。

開源地址:https://github.com/redisson/redisson

7.1 導包

<dependency>  <groupId>org.redisson</groupId>  <artifactId>redisson</artifactId>  <version>3.5.7</version></dependency>

7.2 配置

@Configurationpublic class RedissonConfig {    @Bean  public RedissonClient getRedisson(){    Config config = new Config();    config.useSingleServer().setAddress("redis://localhost:6379");  return Redisson.create(config);  }}

7.3 使?

參考命令匹配列表

8 Redis內存淘汰策略

Redis官?給的警告,當內存不?時,Redis會根據配置的緩存策略淘汰部分的Keys,以保證寫?成功。當?淘汰策略時或者沒有找到適合淘汰的Key時,Redis直接返回 out of memory錯誤。

最?緩存配置
在Redis中,允許?戶設置的最?使?內存??
maxmemory 512G

Redis提供8種(5.0以后)數據淘汰策略:

  • volatile-lru:從已設置過期時間的數據集中挑選最近最少使?的數據淘汰
  • volatile-lfu:從已設置過期的Keys中,刪除?段時間內使?次數最少使? 的key
  • volatile-ttl:從已設置過期時間的數據集中挑選最近將要過期的數據進?淘汰
  • volatile-random:從已設置過期時間的數據集中隨機選擇數據淘汰
  • allkeys-lru:從數據集中挑選最近最少使?的數據淘汰
  • allkeys-lfu:從所有的keys中,刪除?段時間內使?次數最少的key
  • allkeys-random:從數據集中隨機選擇數據淘汰
  • no-enviction(驅逐):禁?驅逐數據(不采?任何淘汰策略。默認即此配置),內存不?時,針對寫操作,返回錯誤信息

建議:了解了Redis的淘汰策略之后,在平時使?時應盡量主動設置/更新key的expire時間,主動剔除不活躍的舊數據,有助于提升查詢性能

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享