1. 程式人生 > >redis快取資料庫 菜鳥福音

redis快取資料庫 菜鳥福音

redis 簡介

​ 簡介:Redis:REmote DIctionary Server(遠端字典伺服器),是完全開源免費的,用C語言編寫的,遵守BSD協議,是一個高效能的(key/value)分散式記憶體資料庫,基於記憶體執行並支援持久化的NoSQL資料庫,是當前最熱門的NoSql資料庫之一,也被人們稱為資料結構伺服器

redis功能

​ 1.記憶體儲存和持久化:redis支援非同步將記憶體中的資料寫到硬碟上,同時不影響繼續服務 ​ 2.取最新N個數據的操作,如:可以將最新的10條評論的ID放在Redis的List集合裡面 ​ 3.模擬類似於HttpSession這種需要設定過期時間的功能 ​ 4.釋出、訂閱訊息系統 ​ 5.定時器、計數器…

redis學習步驟

​ 1.資料型別、基本操作和配置 ​ 2.持久化:RDB/AOF ​ 3.事務的控制 ​ 4.主從複製

windows系統下的redis安裝以及解除安裝

安裝 ​ 進入需要安裝的redis目錄下面執行:redis-server --service-install redis.windows.conf --service-name redis6379 解除安裝 ​ redis-server --service-uninstall --service-name redis 啟動 ​ net start redis 關閉 ​ net stop redis

使用redis

​ 1.啟動redis服務 ​ 2.Redis-cli -p 6379連線埠號為6379的redis ​ 3.輸入set k1 v1,就是往redis資料庫中存放了一個鍵為k1值為v1的資料 ​ 4.輸入 get k1即可獲得資料庫中儲存的k1對應的值 ​ 5.退出當前客戶端:shutdown(退出Redis),quit(返回) ​ 6;關閉redis服務:net stop redis ​ 7:客戶端預設不顯示中文redis-cli --raw -p 6379

需要了解的常識問題

1.redis預設16個數據庫,類似陣列下表從零開始,初始預設使用零號庫 ​ 2.select命令切換資料庫:select 3 切換到下標為3的庫 ​ 3.dbsize命令:檢視當前資料庫的key的數量 ​ 4.flushdb命令:清空當前庫 ​ 5.Flushall命令 : 清空全部庫 ​ 6.redis預設埠號為6379 ​ 7.redis預設不設定密碼 redis5大資料型別介紹

型別簡介

類似於關係型資料庫的資料庫型別,redis的五大資料型別是程式往redis資料庫存資料的5中形式 string:string是redis最基本的型別,一個key對應一個 value(重要) hash:雜湊,類似java裡的Map集合,常用來儲存java裡面的Object(非常重要) list:Redis 列表是簡單的字串列表,按照插入順序排序, 你可以新增一個元素導列表的頭部(左邊)或者尾 部(右邊),類似於LinkList set:Redis的Set是string型別的無序不重複集合。它是通過HashTable實現實現的 zset(sorted set):有序集合,Redis zset 和 set 一樣也 是string型別元素的集合,且不允許重複的成員,不同的是 每個元素都會關聯一個double型別的分數 redis正是通過分數來為集合中的成員進行從小到大的排序.zset的成員是唯一的,但分數(score)卻可以重複.

5大資料型別分類介紹

對key的操作

keys *:查詢該庫中所有key scan:迴圈查詢鍵 exists key:判斷某個key是否存在 expire key 秒鐘:為給定的key設定過期時間 ttl key: 檢視還有多少秒過期,-1表示永不過期,-2表示已過期 type key:檢視你的key是什麼型別 get key:返回 key 所關 聯的字串值,如果 key 不存在那麼返回特殊值 nil set key value:設定值 del key:刪除

對string資料型別的操作

  • append key value:如果 key 已經存在並且是一個字串,APPEND 命令將 value 追加到 key 原來的值的末尾。如果 key 不存在, APPEND 就簡單地將給定 key 設為 value ,就像執行 SET key value 一樣。
  • strlen key :返回 key 所儲存的字串值的長度。
  • incr/decr/incrby/decrby:自增/自減/加指定值/減指定值
  • getrange key start end/setrange key index value:返回 key 中字串值的子字串/用 value 引數覆寫給定 key 所儲存的字串值,從偏移量 index開始。
  • setex key seconds value/setnx key value:將值 value 關聯到 key ,並將 key 的生存時間設為 seconds (以秒為單位).如果 key 已經存在,SETEX 命令將覆寫舊值/將 key 的值設為 value ,當且僅當 key 不存在。
  • mset/mget/msetnx:設定多個/獲得多個/設定多個當key不存在時
  • getset:將給定 key 的值設為 value ,並返回 key 的舊值(old value)。

對list資料型別的操作

  • 資料可重複:(l可以理解為頭,r理解為尾),有下標,它是一個字串連結串列,left、right都可以插入新增;如果鍵不存在,建立新的連結串列;如果鍵已存在,新增內容;如果值全移除,對應的鍵也就消失了。連結串列的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了。 lpush/rpush/lrange key start stop:左加入/右加入/獲取區間資料0 -1代表取全部 lpop key/rpop key:移除並返回列表頭部/尾部 llen key:長度 lrem key count value:移除列表中與引數 value 相等指定count個數的元素。 ltrim key start stop:獲取指定區間的資料在賦值給key rpoplpush k1 k2:將第一個列表尾部元素拿出放到第二個列表頭部 lset key index value:將列表 key 下標為 index 的元素的值設定為 value 。 linsert key before/after pivot value:將值 value 插入到列表 key 當中,位於值 pivot 之前或之後,有多個值預設第一個

對hash資料型別的操作

類似於Map集合,KV模式不變,但V是一個鍵值對 hset/hget/hmset/hmget/hgetall/hdel:插入/獲得/多個插入/獲得鍵值/刪除 hlen key:返回長度 hexists key field:檢視雜湊表 key 中,給定域 field 是否存在。 hkeys/hvals:取出所有的域/取出所有的域的值 hincrby key field increment/hincrbyfloat:為雜湊表 key 中 的域 field 的值加上增量 increment /為雜湊表 key 中的域 field 加上浮點數增量 increment hsetnx:和set類似,key不存在賦值,key存在操作無效

對set資料型別的操作

sadd/smembers key/sismember key member:將一個或多個 member 元素加入到集合 key 當中,已經存在於集合的 member 元素將被忽略/返回集合 key 中的所有成員/判斷 member 元素是否是集合 key 的成員 scard key:獲取集合裡面的元素個數 srem key value:刪除集合中元素 srandmember key num:某個整數(隨機出num個數):那麼返回指定集合中的一個隨機元素 spop key :移除並返回集合中的一個隨機元素。 smove k1 k2 member:將 member 元素從 k1集合移動到 k2集合。 sdiff k1 k2…:差集,在第一個裡面而不在後面任何一個set裡面的項 sinter:交集 sunion:並集

對zset資料型別的操作

在set基礎上,加一個score值。之前set是k1 v1 v2 v3,現在zset是k1 score1 v1 score2 v2 zadd key score member:將一個或多個 member 元素及其 score 值加入到有序集 key 當中 zrem key value:移除key集合中的value值 zcard:返回元素個數 zcount key min max:返回元素個數,scores分數在min和max之間 zrank key value:返回有序集 key 中成員 value的排名。其中有序整合員按 score 值遞增(從小到大)順序排列。zrevrank key value:從大到小 zrange key index [withscores]:返回區間中的資料(分數從小到大) zrevrange key index [withscores];返回區間中的資料(分數從大到小)

配置檔案詳解

  • 看詳解文件 (最後面後面有貼出來)

redis持久化

redis是記憶體資料庫,記憶體裡面的資料在關機或者斷電時會清空,那麼怎麼把記憶體中的時候永久儲存下來就是持久化(把資料儲存到本地硬碟),通常用兩種方式: RDB(Redis DataBase) AOF(Append Only File)

RDB(快照)

在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,也就是行話講的Snapshot快照,它恢復時是將快照檔案直接讀到記憶體裡,Redis會單獨建立(fork)一個子程序來進行持久化,會先將資料寫入到一個臨時檔案中,待持久化過程都結束了,再用這個臨時檔案替換上次持久化好的檔案。整個過程中,主程序是不進行任何IO操作的,這就確保了極高的效能如果需要進行大規模資料的恢復,且對於資料恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺點是最後一次持久化後的資料可能丟失。

RDB配置

按照時間點的順序進行持久化操作

RDB注意事項

1.通過配置滿足條件時快照可以自動觸發,併產生dump.rdb檔案,當然也可以通過save命令手動觸發快照,在save的時候阻塞其他操作,bgsave會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。可以通過lastsave命令獲取最後一次成功執行快照的時間 2.執行flushall命令,也會產生dump.rdb檔案,但裡面是空的,無意義 3.將備份檔案 (dump.rdb) 移動到 redis 安裝目錄並啟動服務可以自動的把硬碟中的資料匯入到記憶體中

RBD優缺點

優點:適合大規模的資料恢復,對資料完整性和一致性要求不高 缺點:在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失最後一次快照後的所有修改,fork的時候,記憶體中的資料被克隆了一份,大致2倍的膨脹性需要考慮

AOF

以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,換言之,redis重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作

AOF配置

AOF預設是關閉的,需要的話可以在配置檔案中開啟修改預設的appendonly no,改為yesAOF產生的檔案的名字預設叫:appendonly.aof

AOF注意事項

AOF採用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮,只保留可以恢復資料的最小指令集.可以使用命令bgrewriteaof,AOF檔案持續增長而過大時,會fork出一條新程序來將檔案重寫(也是先寫臨時檔案最後再rename),遍歷新程序的記憶體中資料,每條記錄有一條的Set語句。重寫aof檔案的操作,並沒有讀取舊的aof檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似

AOF優缺點

如果rdb和aof檔案共存的時候先載入aof檔案,由於如果aof檔案損壞導致redis無法啟動:進入Redis安裝目錄:輸入redis-check-aof --fix appendonly.aof修復 優點:同步持久化每次發生資料變更會被立即記錄到磁碟效能較差但資料完整性比較好 缺點:aof執行效率要慢於rdb,每秒同步策略效率較好,不同步效率和rdb相同

redis讀寫分離以及主從複製

在實際開發過程中一般一臺主伺服器會有多個從伺服器,當主伺服器發生故障的時候,從伺服器能替代主伺服器的功能,那麼就要要求主從伺服器之間的資料要同步,主伺服器實時的吧資料複製到從伺服器上,一般主伺服器複製寫,從伺服器負責讀,實現讀寫分離

redis主從複製配置

當從機連線上主機以後會把主機中所有的資料都同步到從機中,並且從機只能讀不能寫 在從伺服器上配置: slaveof 主機ip 埠號從機每次斷開都要執行該命令,可以寫入配置檔案 slaveof no one:解除從機狀態 info replication :檢視當前主從狀態

redis哨兵模式

當主機發生故障時從從機中自動選出一個替代主機 1.在安裝目錄下建立sentinel.conf檔案(哨兵配置檔案)新增內容格式: sentinel monitor myMonitor 127.0.0.1 6379 2 2.啟動哨兵進入哨兵配置檔案所在目錄:redis-server sentinel.conf --sentinel 3.啟動主機和從機 4.設定主機故障

java操作redis

獲取redis資料庫連線的工具類

package com.zl.util; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class JedisUtil { //連線池物件 private JedisPool jp=null; //建立連線池配置物件 private JedisPoolConfig jpc=null; private static JedisUtil ju=new JedisUtil(); private JedisUtil(){ //建立連線池物件 jpc=new JedisPoolConfig(); //最大空閒連線 jpc.setMaxIdle(8); //最大連線數 jpc.setMaxTotal(100); //最大等待毫秒數 jpc.setMaxWaitMillis(10000); //保證獲得的連線都可用 jpc.setTestOnBorrow(true); jp=new JedisPool(jpc, “localhost”,6380); } public static JedisUtil init(){ return ju; } //返回資料庫連線 public Jedis getJedis(){ return jp.getResource(); } }

序列化方式儲存物件到redis

package com.zl.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerUtil { /*

  • 把一個物件序列化成一個byte陣列以及反序列化 */ public static byte[] getByte(Object o){ byte[] bs=null; //物件輸出流 ObjectOutputStream oos=null; ByteArrayOutputStream bos=null; bos=new ByteArrayOutputStream(); try { oos=new ObjectOutputStream(bos); oos.writeObject(o); bs=bos.toByteArray(); bos.flush(); } catch (IOException e) { e.printStackTrace(); }finally{ try { oos.close(); } catch (IOException e) { e.printStackTrace(); } } return bs; } //反序列化 public static Object getObject(byte[] bs){ Object o=null; ObjectInputStream ois=null; ByteArrayInputStream bis=null; bis=new ByteArrayInputStream(bs); try { ois=new ObjectInputStream(bis); o=ois.readObject(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); }finally{ try { ois.close(); } catch (IOException e) { e.printStackTrace(); } } return o; } }

使用JSON格式字串儲存物件到redis

spring和redis整合

  • 匯入依賴 redis.clientsjedis 2.9.0org.springframework.dataspring-data-redis1.6.0.RELEASE

編寫配置檔案

<?xml version="1.0" encoding="UTF-8"?>
    <property name="maxTotal" value="600" />

    <property name="maxWaitMillis" value="10000" />

    <property name="testOnBorrow" value="true" />
    <property name="port" value="6379" />

    <property name="database" value="0" />

    <property name="poolConfig" ref="poolConfig" />
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">

    <property name="connectionFactory" ref="jedisConnectionFactory" />

</bean>

<!-- 配置RedisCacheManager 

<bean id="redisCacheManager" class="org.springframework.data.redis.cache.RedisCacheManager">

    <constructor-arg name="redisOperations" ref="redisTemplate" />

</bean>-->