在學習redis以前,咱們首先須要瞭解一下NoSQL(非關係數據庫)。非關係型數據庫一般指數據以對象的形式存儲在數據庫中,而對象之間的關係經過每一個對象自身的屬性來決定。html
爲何須要NoSQL?redis
(1) High performance - 高併發讀寫數據庫
(2) Huge Storage - 海量數據的高效率存儲和訪問windows
(3) High Scalability && Hig Availability - 高可擴展性和高可用性緩存
NoSQL數據庫的四大分類:安全
(1) 鍵值(Key - Value)存儲服務器
(2) 列存儲網絡
(3) 文檔數據庫session
(4) 圖形數據庫數據結構
NoSQL的特色:
(1) 易擴展:數據庫種類多,非關係
(2) 靈活的數據模型:無需對存儲的數據模型進行創建
(3) 大數據量,高性能:具備高讀寫性能
(4) 高可用:能夠集成於不少框架
REmote DIctionary Server(Redis)是一個由Salvatore Sanfillippo寫的key-value存儲系統,遵循BSD協議、支持網絡、可基於內存亦可持久化的日誌型、key-value數據庫,一般稱它爲數據結構服務器,由於值(value)能夠是String、Hash、List、Set、Sorted Set等類型。
Redis的應用場景:
(1) 緩存:數據的查詢
(2) 任務隊列:秒殺,搶購
(3) 網站訪問統計
(4) 數據過時處理:精確到毫秒
(5) 應用排行榜
(6) 分佈式集羣架構中的session分離
Redis與其餘 key-value緩存產品有如下三個特色:
- Redis支持數據的持久化,能夠將內存中的數據保存在磁盤中(在寫入的時候可能會存在數據丟失),重啓的時候能夠再次加載進行使用。
- Redis不只僅支持簡單的key-value類型的數據,同時還提供list、set、sorted set、hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
Redis鏈接
Jedis是Redis官方推薦的Java鏈接開發工具。
// 1.設置IP地址和端口 Jedis jedis = new Jedis("localhost", 6379); // 2.保存數據 jedis.set("name", "張三"); String val = jedis.get("name"); System.out.println(val); // 3.關閉資源 jedis.close();
基於鏈接池的鏈接
// 得到鏈接池的配置對象 JedisPoolConfig config = new JedisPoolConfig(); // 設置最大鏈接數 config.setMaxTotal(30); // 設置最大的空閒鏈接數 config.setMaxIdle(10); // 設置最大等待時間 config.setMaxWaitMillis(1000); try( // 得到鏈接池 JedisPool jedisPool = new JedisPool(config, "localhost", 6379); Jedis jedis = jedisPool.getResource(); ) { jedis.set("name1","00001"); String val = jedis.get("name1"); System.out.println(val); }catch (Exception e){ e.printStackTrace(); }
Redis 優點
- 性能極高:Redis最高讀取速度是110000次/s,寫入速度是81000次/s。
- 豐富的數據類型進行存儲。
- 操做原子性:Redis的全部操做都是原子性的,而且支持多個操做經過MULTI和EXEC指令包裹起來後的原子性。
有關redis的下載安裝請查考 https://www.runoob.com/redis/redis-install.html
Window:
- 運行服務端:打開一個 cmd 窗口 使用 cd 命令切換目錄到 redis安裝目錄(如:D:\redis) 運行:redis-server.exe redis.windows.conf 啓動服務端,也能夠直接點擊 redis.window.conf 進行運行。
- 訪問服務端:另啓一個cmd窗口(原來打開的cmd窗口不要關閉,否則沒法訪問服務端),使用cd命令切換到redis的安裝目錄下運行: redis-cli.exe -h 127.0.0.1 -p 6379
Redis配置
Redis的配置文件位於Redis安裝目錄下文件名爲redis.windows.conf中,也能夠經過config命令查看或設置配置項。
Redis CONFIG 命令格式以下:
redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME
可使用 * 號獲取全部配置項:config get *
Redis 存儲數據類型
- 字符串(字符串):string是redis最基本的類型,是二進制安全的,意思是redis的string能夠包含任何數據,好比jpg圖片或者序列化的對象。一個鍵最大存儲爲512MB。
(1) 存:set key1 value1
(2) 取:get key1
(3) 獲取並設置:getSet key1 value2
(4) 刪除:del key1
(5) 遞增:incr key1 (將key1的值遞增一次,若是不存在這個值,則先將這個值設置爲0,而後遞增1;若是不能轉爲整形,則返回錯誤信息。)
(6) 遞減:decr key1 (將key1的值遞減一次,若是不存在這個值,則先將這個值設置爲0,而後遞減1;若是不能轉爲整形,則返回錯誤信息。)
(7) 遞增值:incrby key1 val1 (將key1的值遞增val1,若是不存在這個值,則先將這個值設置爲0,而後遞增val1;若是不能轉爲整形,則返回錯誤信息。)
(8) 遞減值:decrby key1 val1 (將key1的值遞減val1,若是不存在這個值,則先將這個值設置爲0,而後遞減val1;若是不能轉爲整形,則返回錯誤信息。)
(9) 拼湊字符串:append key1 val1 (字符串拼接,將redis中key1的值後面拼接一個val1字符串,返回拼接後字符串的長度,若是不存在,則進行建立設置爲val1)
2.哈希(hash):hash是一個鍵值對集合,是string類型的field和value的映射表,hash特別適合用於存儲對象。
(1) 存:存單個鍵值對 - hset key1 field1 value1 存多個鍵值對 - hmset key1 field1 value1 field2 value2 ... ...
(2) 取:取單個鍵值 - hget key1 field1 取多個鍵值 - hmget key1 field1 field2 ... ... 取key1對象的所有鍵值 - hgetall key1
(3) 刪除:刪除多個鍵值對 - hdel key1 field1 field2 ... 刪除所有 del key1
3.列表(List):list是一個簡單字符串列表,按照插入順序排序。
(1) 兩端添加:左側 - lpush list1 value1 右側 - rpush list1 value2
(2) 查看:lrange list1 start_number end_number (num能夠爲負數,負數表示從尾部開始的索引位置)
(3) 兩端彈出:左側 - lpop list1 右側 - rpop list1
(4) 長度:llen list1
(5) 插入:lpushx list1 value1 (僅當list1存在時纔在左側插入) rpushx list1 value1 (僅當key1存在時纔在右側插入)
(6) 刪除指定值得元素:lrem list1 count_number value1 (刪除list1中count_number個值爲value1的元素,若是count_number > 0,表示從左側開始多少個;若是 count_number < 0,表示從右側開始多少個;若是count_number = 0,表示全是所有值爲value1的元素。)
(7) 在指定位置添加元素:在指定位置插入元素 - lset list1 index1 value1 在指定元素前插入元素 - linsert list1 before value1 value2 在指定元素後插入元素 - linsert list1 after value1 value2
(8) 將list1中的尾部元素取出並添加到list2的頭部:rpoplpush list1 list2
4.集合(Set):set是string類型的無序集合,set集合中不容許出現重複的元素。添加一個string元素到key對應的set集合中,成功返回1,若是元素已經在集合中返回0,若是key對應的set不存在則返回錯誤。
(1) 存:sadd set1 value1 value2 ...
(2) 查看:smembers set1
(3) 刪除:srem set1 value1 value2 ...
(4) 判斷在集合中元素是否存在:sismember myset value1 (若是存在,返回1;不存在返回0)
(5) 差集:sdiff set1 set2 (返回在set1中存在的,在set2不存在的元素)
(6) 交集:sinter set1 set2 (返回同時set1、set2中都存在的元素)
(7) 並集:sunion set1 set2 (返回set1、set2的集合,會自動去重)
(8) 獲取元素個數:scard set1
(9) 隨機返回一個元素:srandmember set1
(10) 將兩個set(set1、set2)的差集存放在另外一個集合(set3)中:sdiffstore set1 set2 set3
(11) 將兩個set(set1、set2)的交集存放在另外一個集合(set3)中:sinterstore set1 set2 set3
(12) 將兩個set(set1、set2)的並集存放在另外一個集合(set3)中:sunionstore set1 set2 set3
5.有序集合zset(Sorted set):zset和set同樣也是string類型元素的集合,且不容許重複的成員。不一樣的是每一個元素都會關聯一個double類型的分數。Redis正是經過分數來爲集合中的成員進行排序。
(1) 添加元素:zadd sort1 score1 value1 score2 value2 ... ... (返回添加元素的個數)
(2) 獲取元素:獲取元素的分數 - zscore sort1 value1 獲取元素的個數 - zcard sort1
(3) 刪除元素:zrem sort1 value1 value2 ... 範圍刪除 - zremrangebyrank sort1 num1 num2 按分數範圍刪除 - zremrangebyscore sort1 score1 score2
(4) 範圍查找:zrange sort num1 num2 顯示分數 - zrange sort1 num1 num2 withscores (分數由小到大) zreverange sort1 num1 num2 withscores (分數由大到小) 按分數由小到大查找 - zrangebyscore sort1 num1 num2 按分數由小到大查找,並顯示分數 - zrangebyscore sort1 num1 num2 withscores 分頁查找 - zrangebyscore sort1 num1 num2 limit start_num stop_num
(5) 分數加減:zscore sort1 score1 value1
(6) 統計分數範圍的元素個數:zcount sort1 score1 score2
Redis的keys的通用操做
(1) 獲取全部key:keys *
(2) 獲取字符開頭的keys:keys prefix?
(3) 刪除key:del key1 key2 ...
(4) 判斷是否存在:exists key1 (返回1-存在,0-不存在)
(5) 重命名:rename key1 new_key1
(6) 設置過時時間(單位:s):expire key1 num
(7) 所剩時間:ttl key1 (無設置過時時間,返回-1)
(8) 獲取類型:type key1
Redis的特性:
- 多數據庫:一個redis能夠包含多個數據庫,客戶端能夠指定鏈接某個redis實例的數據庫,一個redis最多能夠提供16個數據庫,下標爲0~15,客戶端默認鏈接下標爲0的數據庫。(index_表示下標,數值爲0~15)
(1) 指定鏈接那個數據庫:select index_
(2) 將key1移動到另外一個數據庫:move key1 index_
2.Redis事務:事務中,全部命令都會串行執行,事務執行期間,redis不會爲其它的客戶端提供服務,從而保證命令原子化執行。 Redis命令在事務中可能會執行失敗,可是Redis事務不會回滾,而是繼續會執行餘下的命令。這裏和關係型數據庫有點區別,由於關係型數據在這種狀況下都是會回滾的;在multi以後的事務語句,都會將事務放進隊列,這是會檢查語法等,也就是在事務執行期間語法都是沒有問題的,命令出錯的話就是程序有問題,redis不會由於一條錯誤而設計成回滾,下降存儲效率來彌補程序自己的錯誤。redis使用的是串行化隔離機制,串行化機制規定事務的提交必須有序的,若是一個事務打開了,未提交事務或者回滾事務,另外開啓一個事務的話,必須等待前一個事務處理完數據,才能處理數據,不然後面這個事務不能處理數據,因此後提交的數據時會出現鎖爲獲取或者未獲取鎖沒法提交等等錯誤。
(1) 開啓事務:multi
(2) 提交事務:exec
(3) 回滾事務:discard
Redis的持久化:
redis的高性能是由於全部的數據都是保存在內存中。爲了保存數據不被丟失,就須要對數據進行持久化。
- RDB方式:默認支持、不須要配置,在指定的時間間隔內,將內存中的數據集快照寫入磁盤。
- AOF方式:以日誌的方式,記錄服務器所處理的每個操做,在redis啓動的時候會讀取該文件,來從新構建數據庫,保證啓動後數據庫中的數據是完整的。
- 不持久化:經過配置禁用redis持久化的功能,這樣redis只是一個緩存的工具
- 能夠RDE、AOF結合使用。
RDB:
優點:
1、redis的數據庫只包含一個文件,對於文件備份來講很完美
2、備份:如每一個小時歸檔一次最近24小時的數據,同時天天歸檔一次最近30天的數據,那麼當系統出現災難性故障的時候,能夠恢復(對於災難恢復來講RDB是很是好的選擇,能夠將一個單獨的文件壓縮後轉移到其餘的存儲介質上)
3、性能最大化:對於redis進程而言,在開始持久化的時候,它惟一須要作的是分叉處一些子進程,以後的由子進程完成這些持久化的工做,極大的避免服務器進程執行IO操做
4、與AOF相比優點:啓動效率更高
劣勢:
1、想保證數據的高可用性(最大限度避免數據的丟失),那RDB不是一個很好的選擇(若是系統在定時持久化以前發生故障,那麼數據還沒來得及往磁盤上寫,數據就已經丟失了)
2、子進程協助完成持久化,所以當數據集很大的時候,可能會致使服務器中止幾百毫秒
配置:
redis 默認使用RDB 方式持久化,配置文件爲redis.conf(window下爲redis.windows-service.conf)
- save 900 1:表示每900秒至少一個key發生變化,就保存一次
- save 300 10:表示每300秒至少有10個key發生變化,就保存一次
- save 60 10000:表示每60秒至少有10000個key發生變化,就保存一次
- dbfilename dump.rdb:表示存儲數據的文件名
- dir ./ :表示數據的存儲路徑
AOF
優點:
1、更高的數據安全性。同步策略:每秒同步,每修改同步、不一樣步。每秒同步:異步完成,效率高,系統出現宕機,那麼這一秒中修改的數據就會丟失;每修改同步:能夠看做同步持久化,麼一次發生數據的變化,都會當即寫到磁盤當中,效率低,可是最安全
2、對日誌文件的寫入操做,採用的是追加模式(append),所以在寫入過程當中,即便出現了宕機的狀況,也不會破壞日誌文件中已經存在的內容。若是本次寫入進行到一半就出現宕機,那麼這種方式也沒必要擔憂,redis在下一次啓動以前,能夠經過redis-check-aof這個工具,幫助咱們解決數據一致性的問題
3、若是日誌過大,redis能夠自動啓動重寫機制,redis以append模式不斷的將修改的數據寫入到老的磁盤文件當中,同時redis會建立一個新的文件,用於記錄此期間產生的哪些修改命令被執行。所以,在進行重寫切換的時候,能夠更好的去保證數據的安全性
4、AOF包含一個格式清晰易於理解的日誌文件用於記錄全部的修改操做,也能夠經過這個文件完成數據的重建
劣勢
1、對於相同數量的數據集而言,AOF的文件要比RDB的文件大一些
2、根據同步策略的不一樣,AOF在效率上每每低於RDB
配置:
redis 配置文件爲redis.conf(window下爲redis.windows-service.conf)
- 打開 AOF:appenddonly yes
- 日誌文件名稱:appendfilename 「appendonly.aof」
- 設置同步策略:每秒同步 - appendfsync always; 每修改同步 - appendfsync everysec; 不一樣步 - appendfsync no;
AOF下的Redis持久化:啓動後,插入一些數據後,經過flushall清空數據庫,而後關閉redis,從新啓動redis以前,修改日誌文件配置文件,將最後一行的flushAll刪除,並保存,而後重啓redis