redis資料庫NoSQL的介紹安裝和使用
Redis使用
- redis介紹
- 什麼是NoSQL
NoSQL資料庫的產生就是為了解決大規模資料集合多重資料種類帶來的挑戰,尤其是大資料應用難題。目前一些主流的NOSQL產品:
-
- NoSQL資料庫的分類
- 鍵值(Key-Value)儲存資料庫
- NoSQL資料庫的分類
相關產品有Tokyo Cabinet/Tyrant、Redis、Voldemort、Berkeley DB,主要應用於內容快取,主要用於處理大量資料的高訪問負載。
-
-
- 列儲存資料庫
-
相關產品有Cassandra, HBase, Riak,典型應用於分散式的檔案系統。
-
-
- 文件型資料庫
-
相關產品有CouchDB、MongoDB,典型應用於Web應用,可以突破傳統關係型資料庫的結構限制,儲存資料更為靈活。
-
-
- 圖形(Graph)資料庫
-
相關資料庫有Neo4J、InfoGrid、Infinite Graph,典型應用於社交網路,儲存資料採用圖結構利用圖結構相關演算法。
-
- 什麼是redis
-
- redis歷史發展
2008年,義大利的一家創業公司Merzia推出了一款基於MySQL的網站實時統計系統LLOOGG,然而沒過多久該公司的創始人 Salvatore Sanfilippo便 對MySQL的效能感到失望,於是他決定親自為LLOOGG量身定做一個數據庫,並於2009年開發完成,這個資料庫就是Redis。 不過Salvatore Sanfilippo並不滿足只將Redis用於LLOOGG這一款產品,而是希望更多的人使用它,於是在同一年Salvatore Sanfilippo將Redis開源釋出,並開始和Redis的另一名主要的程式碼貢獻者Pieter Noordhuis一起繼續著Redis的開發,直到今天。
Salvatore Sanfilippo自己也沒有想到,短短的幾年時間,Redis就擁有了龐大的使用者群體。Hacker News在2012年釋出了一份資料庫的使用情況調查,結果顯示有近12%的公司在使用Redis。國內如新浪微博、街旁網、知乎網,國外如GitHub、Stack Overflow、Flickr等都是Redis的使用者。
VMware公司從2010年開始贊助Redis的開發, Salvatore Sanfilippo和Pieter Noordhuis也分別在3月和5月加入VMware,全職開發Redis。完全免費
-
- redis的應用場景
Redis廣泛應用於快取,布式叢集架構中的session分離,聊天室的線上好友列表,任務佇列,應用排行榜,網站訪問統計,資料過期處理等場景。
- redis的安裝
- redis安裝環境
redis是C語言開發,建議在linux上執行,本教程使用Centos6.4作為安裝環境。
安裝redis需要先將官網下載的原始碼進行編譯,編譯依賴gcc環境,如果沒有gcc環境,需要安裝gcc:yum install gcc-c++。
-
- redis安裝
我們使用的Redis版本為redis3.0版本,首先可以從官網下載Redis壓縮包http://download.redis.io/releases/redis-3.0.0.tar.gz,然後將下載的redis上傳到虛擬機器的/usr/local目錄下。
接下來解壓Redis壓縮包,使用命令:tar -zxvf redis-3.0.7.tar.gz
進入解壓後的目錄進行編譯和安裝,編譯使用命令make,安裝使用命令make install。安裝成功後執行Redis服務,如果出現以下介面,則Redis安裝成功,啟動命令:redis-server。
Redis安裝之後,我們在/usr/local/bin下可以發現編譯之後的Redis執行檔案。
-
- redis的啟動
- 前端模式啟動
- redis的啟動
直接執行redis-server將以前端模式啟動,前端模式啟動的缺點是佔用終端,同時ssh命令視窗關閉則redis-server程式結束,所以不推薦使用此方法。
-
-
- 後端模式啟動
-
修改redis.conf配置檔案, 將daemonize 設定yes 以後即可以後端模式來啟動Redis。
修改之後用當前修改後的配置檔案來啟動Redis伺服器。
此時我們可以使用命令的方式檢視服務是否已經啟動。
我們發現Redis服務已經啟動,預設使用6379埠。
-
-
- 啟動多個redis程序
-
啟動多個Redis服務,一般採用定義多個對應的配置檔案的方式來啟動不同配置的Redis服務,同時需要分別修改每一個Redis伺服器啟動的埠號。這裡我們啟動兩個Redis伺服器,分別使用6379和6380埠。
GENERAL port 6380
首先我們建立兩個目錄。
在兩個目錄中定義redis的配置檔案,這裡我們將redis預設的配置檔案拷貝過來,並修改對應的埠號,然後分別啟動兩個Redis服務。
-
- redis的停止
要停止正在執行的Redis服務,可以採用Linux命令的方式直接殺掉Redis服務的程序,也可以使用Redis客戶端想伺服器傳送shutdown指令來關閉Redis伺服器。
-
- 使用redis客戶端
在redis的安裝目錄中有redis的客戶端,即redis-cli(Redis Command Line Interface),它是Redis自帶的基於命令列的Redis客戶端。
-
-
- 連線Redis伺服器
-
使用redis-cli命令即可連線預設的本機6379埠的Redis伺服器。如下圖表示連線成功。
如果希望遠端連線其他主機或者其他埠的Redis伺服器,可以加上以下的引數,使用-h設定遠端主機的ip,使用-p設定遠端主機的埠號。
-
-
- 向Redis伺服器傳送命令
-
redis-cli連上redis服務後,可以在命令列向Redis伺服器傳送命令。
-
-
-
- ping命令
-
-
Redis提供了PING命令來測試客戶端與Redis的連線是否正常,如果連線正常會收到回覆PONG。
-
-
-
- set/get命令
-
-
使用set和get可以向redis設定資料、獲取資料。
-
-
-
- del命令
-
-
del命令用來刪除指定key的內容。
-
-
-
- keys*命令
-
-
keys*命令用來檢視當前redis資料庫中存在的key的名稱。
-
-
-
- flushdb命令
-
-
flushdb命令用來清空當前資料庫中的所有資料。
-
- Redis多資料庫
一個Redis資料庫可以包括多個數據庫,客戶端可以指定連線某個redis例項的哪個資料庫,就好比一個mysql中建立多個數據庫,客戶端連線時指定連線哪個資料庫。一個redis例項預設提供16個數據庫,這由啟動的配置檔案中指定,下標從0到15,客戶端預設連線第0號資料庫,也可以通過select選擇連線哪個資料庫,不同資料庫中的資料不能共享。
需要注意的問題是,如果我們使用flushall命令清空某一個庫中的資料時,其他庫中的資料也會被清空,因此,在我們不同的業務訪問Redis伺服器時應該選擇不同的Redis伺服器,而不是同一個伺服器內部的不同的資料庫。
- Jedis的使用
- Jedis介紹
Redis不僅是使用命令來操作,現在基本上主流的語言都有客戶端支援,比如java、C、C#、C++、php、Node.js、Go等。
在官方網站裡列一些Java的客戶端,有Jedis、Redisson、Jredis、JDBC-Redis、等其中官方推薦使用Jedis和Redisson。 在企業中用的最多的就是Jedis,下面我們就重點學習下Jedis。
-
- 通過jedis連線redis
- 新增jar包
- 通過jedis連線redis
要使用Jedis需要加入Jedis對應的jar包。我們使用maven來構建工程,因此直接使用jedis的jar包依賴座標即可。
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.7.0</version> </dependency> |
Maven會自動在工程中新增jedis需要依賴的jar包。
-
-
- 單例項連線Redis
-
通過建立單例項jedis物件連線redis服務,直接建立Jedis物件即可,如下程式碼:
package com.igeek.redis_jedis_01; import org.junit.Test; import redis.clients.jedis.Jedis; public class AppTest{ @Test public void testJedisSingle() { //建立Jedis物件,傳遞兩個引數:第一個host為redis伺服器的名稱,第二個為redis伺服器的埠號 Jedis jedis = new Jedis("192.168.5.128", 6379); //進行設值操作 jedis.set("username","zhangsan"); //從redis中取值 String username = jedis.get("username"); System.out.println("username:"+username); } } |
-
-
- 使用連線池連線Redis
-
通過單例項連線redis不能對redis連線進行共享,可以使用連線池對redis連線進行共享,提高資源利用率,使用jedisPool連線redis服務,如下程式碼:
package com.igeek.redis_jedis_01; import org.junit.Test; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; public class AppTest{ @Test public void testJedisPool(){ //建立JedisPool連線池配置 JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); //設定連線池的最大連線數 jedisPoolConfig.setMaxTotal(20); //設定連線池的最大連線空閒數 jedisPoolConfig.setMaxIdle(2); //設定redis伺服器的主機 String host = "192.168.5.128"; //設定redis伺服器的埠 int port = 6379; //建立JedisPool連線池物件 JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port); //獲取Jedis物件 Jedis jedis = jedisPool.getResource(); //存入資料 jedis.set("info", "message"); //獲取資料 String info = jedis.get("info"); System.out.println("info:"+info); //關閉資源 jedisPool.close(); } } |
- redis的資料型別
- String型別
redis中沒有使用C語言的字串表示,而是自定義一個數據結構叫SDS(simple dynamic string)即簡單動態字串。redis的字串是二進位制安全的,存入什麼資料取出的還是什麼資料。
String型別的的常用命令有:
-
-
- 賦值命令
-
redis中賦值操作使用set命令,語法 set key value。
範例:向redis中插入資料,鍵為name,值為zhangsan。
如果希望一次性插入多條資料,可以使用mset命令,語法mset key1 value1 key2 value2 …
範例:一次性向redis中插入以下資料,id為1,age為 20。
-
-
- 取值命令
-
redis中進行取值操作使用get命令,語法:get key。
範例:獲取鍵為name的資料的值
需要注意的是,如果通過get命令獲取資料時,給定的鍵不存在,則返回(nil),表示查詢結果為空。
如果希望一次性從redis中獲取多個鍵對應的資料的值,可以使用mget命令,語法:mget key1 key2 …
範例:獲取redis中id,name,age的資料的值。
我們也可以使用getset命令,在獲取對應鍵的資料的同時,為該鍵指定新的值。語法:getset key newValue。
範例:獲取name對應的名稱,並將名稱的值改為lisi。
-
-
- 刪除命令
-
在Redis中刪除資料使用del命令,語法:del key。
範例:刪除id對應的資料的值。
如果需要直接清空該庫中所有資料,可以使用flushdb命令。
範例:清空當前資料庫中的資料。
如果要清空所有庫中的所有資料使用flushall命令。
範例:清理redis所有庫中的所有資料。
-
-
- 數值遞增
-
當儲存的字串是整數時,Redis提供了一個實用的命令incr,其作用是讓當前鍵值遞增,並返回遞增後的值。語法:incr key。
範例:向資料庫中插入資料num初始值為1,然後自增加1。
以上的自增表示每次加1,如果需要按照指定的資料來進行增長,可以使用incrby命令,語法:incrby key increment。
範例:使用incrby命令將num的資料值加10。
-
-
- 數值遞減
-
當需要對資料進行遞減操作時,使用decr命令,語法:decr key。
範例:將num對應資料的值遞減1。
如果希望遞減指定的數值,可以使用decrby,語法:decrby key decrement。
範例:將num對應資料的值減10.
-
-
- 追加資料
-
在Redis中可以使用append命令向指定資料的末尾追加內容,語法:append key value。
範例:向info資料的末尾新增內容。
注意:在插入資料時,字串的雙引號預設可以省略,但是如果字串中包含空格的情況,需要加上雙引號,否則空格會被忽略。
-
-
- 獲取長度
-
使用strlen命令可以返回指定鍵對應的值的長度,如果鍵不存在則返回0。語法:strlen key。
範例:獲取info對應的資料的長度。
-
- hash型別
hash叫雜湊型別,它提供了欄位和欄位值的對映。欄位值只能是字串型別,不支援雜湊型別、集合型別等其它型別。
hash型別的的常用命令有:
-
-
- 賦值命令
-
向hash中插入獲設定資料沒使用hset命令,語法:hset key field value。
範例:向redis中插入user的name屬性值為songjiang。
如果希望從redis中一次性設定多個欄位的值,可以使用hmset,語法:hmset key field1 value1 field2 value2 …
範例:向redis中插入user的id和age屬性。
-
-
- 取值命令
-
從hash中獲取資料使用hget命令,語法:hget key field。
範例:獲取user的name屬性的值。
使用hmget可以一次性獲取多個欄位的值。語法:hmget key field1 field2 field3 …
範例:獲取user的id,name,age欄位的值。
可以使用hgetall命令,或者指定鍵的所有欄位和欄位的值。語法:hgetall key。
使用HKEYS和HVALS命令可以分別用來獲取指定鍵的所有鍵和所有值。
範例:獲取user的所有鍵和所有值。
-
-
- 判斷欄位是否存在
-
判斷欄位是否存在使用HEXISTS命令,如果存在則返回1,如果不存在則返回0 ,語法:HEXISTS key field
範例:判斷user是否存在。
-
-
- 獲取欄位數量
-
獲取欄位數量使用HLEN命令,如果鍵不存在則返回0,語法HLEN key。
範例:獲取指定鍵的資料中鍵的數量。
-
-
- 刪除命令
-
要刪除一個或多個欄位,使用hdel命令,語法:HDEL key field [field ...]。
範例:刪除user的id欄位的值。
範例:刪除user的name和age欄位。
-
-
- 增加數字
-
如果hash中的欄位儲存的值為數值型別,可以進行自增操作。語法:HINCRBY key field increment。
範例:將user的age欄位的值增加1.
-
- list型別
列表型別(list)可以儲存一個有序的字串列表,常用的操作是向列表兩端新增元素,或者獲得列表的某一個片段。
列表型別內部是使用雙向連結串列(double linked list)實現的,所以向列表兩端新增元素的時間複雜度為0(1),獲取越接近兩端的元素速度就越快。這意味著即使是一個有幾千萬個元素的列表,獲取頭部或尾部的10條記錄也是極快的。
list型別的的常用命令有:
-
-
- 新增資料
-
Redis列表採用雙向連結串列實現,因此在插入資料時可以從兩端分別操作,向列表左邊增加元素使用lpush命令,向列表右邊增加元素使用rpush命令。
範例:向列表中插入資料
-
-
- 檢視列表
-
LRANGE命令是列表型別最常用的命令之一,獲取列表中的某一片段,將返回start、stop之間的所有元素(包含兩端的元素),索引從0開始。索引可以是負數,如:“-1”代表最後邊的一個元素。
範例:獲取列表nums和nums2中的資料
從以上獲取的資料結構來看,我們發現從列表的左側插入資料,在列表中資料以倒敘存放,從列表的右側插入資料則是正序存放。
-
-
- 獲取資料
-
在列表中可以使用lpop和rpop分別列表的左側和右側彈出一個數據,該資料會首先返回,然後再從原列表中刪除。
範例:彈出nums的左側資料。
範例:彈出nums的右側資料。
-
-
- 獲取列表中元素的個數
-
使用LLEN命令可以獲取列表中元素的個數。範例:LLEN key
範例:獲取nums2列表中元素的個數。
-
-
- 刪除列表中指定的值
-
LREM命令會刪除列表中前count個值為value的元素,返回實際刪除的元素個數。根據count值的不同,該命令的執行方式會有所不同:
- 當count>0時, LREM會從列表左邊開始刪除。
- 當count<0時, LREM會從列表後邊開始刪除。
- 當count=0時, LREM刪除所有值為value的元素。
範例:刪除nums中的4元素
-
-
- 獲得/設定指定索引的元素值
-
n 獲得或者設定指定索引的元素值分別使用lindex和lset命令。
範例:獲取nums列表中索引2對應的資料
範例:將nums中索引2對應的資料改為x
-
-
- 只保留列表指定片段
-
List中使用ltrim命令對列表中的資料進行擷取操作,只保留指定資料片段。語法:ltrim key start stop。
範例:擷取nums列表中索引從1開始到3的資料
-
-
- 向列表中插入元素
-
向列表中指定位置插入元素可以使用linsert命令,語法:LINSERT key BEFORE|AFTER pivot value。
範例:向nums列表中的x元素後面插入元素y
-
-
- 將元素從一個列表轉移到另一個列表中
-
使用RPOPLPUSH命令可以將元素從一個列表轉移到另一個列表中。語法:RPOPLPUSH source destination。
範例:將元素從一個列表轉移到另一個列表中
-
- set型別
集合型別的常用操作是向集合中加入或刪除元素、判斷某個元素是否存在等,由於集合型別的Redis內部是使用值為空的散列表實現,所有這些操作的時間複雜度都為0(1)。 Redis還提供了多個集合之間的交集、並集、差集的運算。
set型別的的常用命令有:
-
-
- 增加/刪除元素
-
集合中新增資料使用sadd命令,語法sadd key member [member…].
範例:向set集合中新增資料
-
-
- 獲得集合中的所有元素
-
獲取集合中所有元素使用SMEMBERS命令,語法:SMEMBERS key
範例:獲取set集合中的所有元素
-
-
- 集合的差集運算
-
屬於A並且不屬於B的元素構成的集合,使用命令SDIFF,語法:SDIFF key [key ...]
範例:集合的差集
-
-
- 集合的交集運算
-
屬於A並且也屬於B的元素構成的集合,使用命令SINTER,語法:SINTER key [key ...]
範例:集合的交集
-
-
- 集合的並集運算
-
屬於A並且或者屬於B的元素構成的集合,使用命令SUNION,語法:SUNION key [key ...]
範例:集合的並集
-
-
- 獲得集合中元素的個數
-
n 獲得集合中元素的個數,使用SCARD命令,如果集合不存在則返回0,語法:SCARD key
範例:獲取集合set中元素的個數
-
-
- 從集合中彈出一個元素
-
從集合中彈出一個元素使用spop命令,語法:spop key
範例:從set集合中彈出一個元素
-
- sorted set型別
在集合型別的基礎上有序集合型別為集合中的每個元素都關聯一個分數,這使得我們不僅可以完成插入、刪除和判斷元素是否存在在集合中,還能夠獲得分數最高或最低的前N個元素、獲取指定分數範圍內的元素等與分數有關的操作。
在某些方面有序集合和列表型別有些相似。
1、二者都是有序的。
2、二者都可以獲得某一範圍的元素。
但是,二者有著很大區別:
1、列表型別是通過連結串列實現的,獲取靠近兩端的資料速度極快,而當元素增多後,訪問中間資料的速度會變慢。
2、有序集合型別使用散列表實現,所有即使讀取位於中間部分的資料也很快。
3、列表中不能簡單的調整某個元素的位置,但是有序集合可以(通過更改分數實現)
4、有序集合要比列表型別更耗記憶體。
sorted set型別的的常用命令有:
-
-
- 增加元素
-
向有序集合中加入一個元素和該元素的分數,如果該元素已經存在則會用新的分數替換原有的分數。返回值是新加入到集合中的元素個數,不包含之前已經存在的元素。語法:ZADD key score member [score member ...]
範例:向有序集合中新增資料
-
-
- 獲得排名在某個範圍的元素列表
-
獲得排名在某個範圍的元素列表使用zrange命令,語法:ZRANGE key start stop [WITHSCORES]
範例:獲取score中的元素
以上是根據分數進行升序排列,如果要進行降序排列,我們使用命令ZREVRANGE。
範例:降序獲取score中的元素
-
-
- 刪除元素
-
移除有序集key中的一個或多個成員使用命令ZREM,不存在的成員將被忽略。語法:ZREM key member [member ...]
範例:移除score中zhangsan元素
-
-
- 獲得指定分數範圍的元素
-
獲得指定分數範圍的元素使用ZRANGEBYSCORE命令,語法:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
範例:獲取score中分數在60 – 80分之間的資料元素。
-
-
- 增加某個元素的分數,返回值是更改後的分數
-
增加某個元素的分數,返回值是更改後的分數,使用命令ZINCRBY,語法:ZINCRBY key increment member
範例:給lisi加4分
-
-
- 獲得集合中元素的數量
-
獲取集合中元素的數量使用ZCARD命令,語法:ZCARD key。
範例:獲取score集合中元素的個數
-
-
- 獲得指定分數範圍內的元素個數
-
獲得指定分數範圍內的元素個數使用命令zcount,語法:ZCOUNT key min max。
範例:獲取score中分數在70-90之間的元素個數
-
-
- 按照排名範圍刪除元素
-
按照排名範圍刪除元素使用命令ZREMRANGEBYRANK,語法:ZREMRANGEBYRANK key start stop
範例:刪除score中排名前兩位的元素
-
-
- 按照分數範圍刪除元素
-
按照分數範圍刪除元素使用命令ZREMRANGEBYSCORE,語法:ZREMRANGEBYSCORE key start stop
範例:刪除score中分數在60 -80之間的元素
<