Redis是一個使用ANSI C編寫的開源、支持網絡、基於內存、可選持久性的鍵值對存儲數據庫 ——維基百科java
能夠簡單的說,Redis就是一款高性能的NoSQL數據庫linux
咱們前面所學習的MySQL數據庫是典型的的SQL數據庫也就是傳統的關係型數據庫,而咱們今天學習的Redis數據庫則是一款NoSQL數據庫,也叫做非關係型數據庫,它與咱們熟悉的MySQL等的概念徹底是不同的,它是一項全新的數據庫理念,咱們帖一組百度百科的解釋git
NoSQL,泛指非關係型的數據庫。隨着互聯網web2.0網站的興起,傳統的關係數據庫在處理web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,出現了不少難以克服的問題,而非關係型的數據庫則因爲其自己的特色獲得了很是迅速的發展。NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題 ——百度百科github
說明:咱們如今所看到的的博客,RSS,P2P,微博,抖音等均屬於 Web2.0的產物,Web2.0相比較過去的Web1.0更加註重於用戶的交互,用戶不只能夠瀏覽,還能夠上傳一些資源到網站上,例如圖片文字或者說短視頻等,使得用戶也參與到了網站內容的製造中去了web
有人會說,NoSQL = Not SQL ,可是我更傾向這樣理解 NoSQL = Not only SQL ,咱們不能以一個絕對的結論來斷定兩項技術的好壞,每一項技術的產生都有其特定的緣由,在我看來,NoSQL更適合做爲SQL數據庫的補充,因爲海量數據的出現,性能的要求高了起來,而NoSQL這種產物,對於結構簡單可是數據量大的數據處理起來要比傳統的SQL快不少,可是一樣的,其邏輯運算就必須很簡單,不然它也是力不從心的redis
在我看來,能夠簡單的說,NoSQL就是以功能換取性能,可是須要處理複雜的業務邏輯還須要使用關係型數據庫,因此說想要在模型中徹底用NoSQL替代SQL是不現實的,二者更像是互補的關係數據庫
SQL的好處:windows
市面上的NoSQL產品很是多,咱們今天所要介紹的就是其中一款基於鍵值存儲的數據庫——Redis緩存
咱們在一開始提到了,Redis就是一款高性能的NoSQL數據庫,那麼它的應用場景是什麼呢?安全
用於用戶內容緩存,能夠處理大量數據的高訪問負載,例如:數據查詢,新聞,商品內容
任務隊列,例如:秒殺,12306
在線好友列表
應用、網站訪問統計排行
因爲其基於鍵值存儲,那麼能夠支持的存儲的類型有什麼呢?
字符串類型 - String
列表 - list:linkedlist
集合 - set
有序集合 - sortedset
哈希 - hash:map
官網:redis.io
因爲官網訪問速度過慢,咱們能夠訪問對應的中文網:www.redis.net.cn
下載,解壓,編譯:
$ wget http://download.redis.io/releases/redis-5.0.4.tar.gz
$ tar xzf redis-5.0.4.tar.gz
$ cd redis-5.0.4
$ make
複製代碼
二進制文件是編譯完成後在src目錄下. 運行以下:
$ src/redis-server
複製代碼
你能使用Redis的內置客戶端進行進行redis代碼的編寫,例如咱們存入一個鍵值 name-zhangsan
$ src/redis-cli
redis> set name zhangsan
OK
redis> get name
"zhangsan"
複製代碼
咱們能夠去github中尋找windows版本,不過版本會有所滯後
解壓便可用
redis-server.exe:redis服務器端
redis-cli.exe:redis的客戶端
redis.windows.conf:配置文件
- 127.0.0.1:6379> set address beijing
- OK
複製代碼
- 127.0.0.1:6379> get address
- 「beijing」
複製代碼
- 127.0.0.1:6379> del address
- (integer) 1
複製代碼
添加一個元素到列表的頭部(左邊)或者尾部(右邊)
127.0.0.1:6379> lpush listDemo zhangsan
(integer) 1
127.0.0.1:6379> lpush listDemo lisi
(integer) 2
127.0.0.1:6379> rpush listDemo wangwu
(integer) 3
複製代碼
1) "lisi"
2) "zhangsan"
3) "wangwu"
複製代碼
set:String 類型的無序集合,且元素不能重複
127.0.0.1:6379> sadd setDemo aaa
(integer) 1
127.0.0.1:6379> sadd setDemo aaa
(integer) 0
複製代碼
127.0.0.1:6379> smembers setDemo
1) "aaa「 複製代碼
127.0.0.1:6379> srem setDemo aaa
(integer) 1
複製代碼
sortedset 和 set 同樣也是 string 類型元素的集合,且不容許重複的元素
不一樣的是每一個元素都會關聯一個double類型的分數,redis正是經過分數來爲集合中的成員進行從小到大的排序
有序集合的成員是惟一,但分數(score)卻能夠重複
127.0.0.1:6379> zadd sortedsetDemo 20 zhangsan
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 10 lisi
(integer) 1
127.0.0.1:6379> zadd sortedsetDemo 60 wangwu
(integer) 1
複製代碼
127.0.0.1:6379> zrange sortedsetDemo 0 -1
1) "lisi"
2) "zhangsan"
3) "wangwu"
複製代碼
127.0.0.1:6379> zrem sortedsetDemo wangwu
(integer) 1
複製代碼
127.0.0.1:6379> hset hashDemo username admin
(integer) 1
127.0.0.1:6379> hset hashDemo password admin
(integer) 1
複製代碼
127.0.0.1:6379> hget hashDemo password
"admin"
複製代碼
127.0.0.1:6379> hgetall hashDemo
1) "username"
2) "admin"
3) "password"
4) "admin"
複製代碼
127.0.0.1:6379> hdel hashDemo username
(integer) 1
複製代碼
開篇已經講過,Redis是一個內存數據庫,也就是說,咱們的數據所有存儲在內存中,而咱們常見的MySQL和Oracle等SQL數據庫會將數據存儲到硬盤中,凡事都是有利有弊,雖然內存數據庫讀寫速度要比在硬盤中讀寫的數據庫快的多,可是卻出現了一個很麻煩的問題,也就是說,當 Redis 服務器重啓或者宕機後,內存中的數據會所有丟失,爲了解決這個問題,Redis提供了一種持久化的技術,也就是將內存中的數據存儲到硬盤中去,往後方便咱們使用這些文件恢復數據庫中的數據
RDB:必定的時間內,檢測key的變化狀況,而後持久化數據
咱們想要配置它,須要編輯 redis.windows.conf 配置文件
# Save the DB on disk:
#
# save <seconds> <changes>
#
# Will save the DB if both the given number of seconds and the given
# number of write operations against the DB occurred.
#
# In the example below the behaviour will be to save:
# after 900 sec (15 min) if at least 1 key changed
# after 300 sec (5 min) if at least 10 keys changed
# after 60 sec if at least 10000 keys changed
# ......省略部分
save 900 1
save 300 10
save 60 10000
複製代碼
咱們須要修改的就是最後三行,前面的說明的意思是,若是給定的秒數和給定的對數據庫的寫操做數同時發生,那麼將保存數據庫,也就是說,它的配置是根據save後面的兩個數字,根聽說明可知,第一個數字表明間隔時間,第二個數表明操做數據的數量
例如第一個 save 900 1 ,就是說每900秒且,至少一個 key 被改變則保存數據
咱們根據本身具體項目的須要設置好後,須要從新啓動Redis的服務器,而且咱們須要指定配置文件,咱們先指向到Redis指定目錄下, 而後輸入命令 redis-server.exe redis.windows.conf
例如我本地:D:\Tools\Redis-x64-3.2.100>redis-server.exe redis.windows.conf
AOF:每一次操做後,就持久化數據
咱們一樣能夠在 redis.windows.conf 文件配置
咱們找到這一行
appendonly no
no表明關閉aof,改成yes表明開啓
還有這一行
# appendfsync no
:不進行持久化
咱們能夠修改 no 位置的值
Jedis is a blazingly small and sane Redis java client.
Jedis was conceived to be EASY to use.
Jedis 是一款可讓咱們在java中操做redis數據庫的工具,下載其jar包導入便可,使用仍是很是簡單的
//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();
//存儲
jedis.set("address","beijing");
//獲取
String address = jedis.get("address");
//關閉鏈接
jedis.close();
複製代碼
補充:setex() 方法能夠存儲數據,而且指定過時時間
//將aaa-bbb存入,且10秒後過時
jedis.setex("aaa",10,"bbb")
複製代碼
//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();
//存儲
jedis.lpush("listDemo","zhangsan","lisi","wangwu");//從左
jedis.rpush("listDemo","zhangsan","lisi","wangwu");//從右
//獲取
List<String> mylist = jedis.lrange("listDemo", 0, -1);
//刪除,而且返回元素
String e1 = jedis.lpop("listDemo");//從左
String e2 = jedis.rpop("listDemo");//從右
//關閉鏈接
jedis.close();
複製代碼
//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();
//存儲
jedis.sadd("setDemo","zhangsan","lisi","wangwu");
//獲取
Set<String> setDemo = jedis.smembers("setDemo");
//關閉鏈接
jedis.close();
複製代碼
//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();
//存儲
jedis.zadd("sortedsetDemo",20,"zhangsan");
jedis.zadd("sortedsetDemo",10,"lisi");
jedis.zadd("sortedsetDemo",60,"wangwu");
//獲取
Set<String> sortedsetDemo = jedis.zrange("sortedsetDemo", 0, -1);
//關閉鏈接
jedis.close();
複製代碼
//獲取鏈接,空構造表明默認值 "localhost",6379端口
Jedis jedis = new Jedis();
//存儲
jedis.hset("hashDemo","name","lisi");
jedis.hset("hashDemor","age","20");
//獲取
String name = jedis.hget("hashDemo", "name");
//獲取全部數據
Map<String, String> user = jedis.hgetAll("hashDemo");
Set<String> keySet = user.keySet();
for (String key : keySet) {
//獲取value
String value = user.get(key);
System.out.println(key + ":" + value);
}
//關閉鏈接
jedis.close();
複製代碼
爲何咱們要使用鏈接池呢?
咱們要使用Jedis,必須創建鏈接,咱們每一次進行數據交互的時候,都須要創建鏈接,Jedis雖然具備較高的性能,但創建鏈接卻須要花費較多的時間,若是使用鏈接池則能夠同時在客戶端創建多個鏈接而且不釋放,鏈接的時候只須要經過必定的方式獲取已經創建的鏈接,用完則歸還到鏈接池,這樣時間就大大的節省了
//建立一個配置對象
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxIdle(10);
//建立Jedis鏈接池對象
JedisPool jedisPool = new JedisPool(config,"localhost",6379);
//獲取鏈接
Jedis jedis = jedisPool.getResource();
//使用
jedis.set("setDemo","zhangsan");
//關閉 歸還到鏈接池中
jedis.close();
複製代碼
public class JedisPoolUtils {
private static JedisPool jedisPool;
//靜態代碼初始化池配置
static{
//建立Properties對象
Properties pro = new Properties();
//讀取配置文件
InputStream is = JedisPoolUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
//關聯文件
try {
pro.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//獲取數據,配置到JedisPoolConfig
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(Integer.parseInt(pro.getProperty("maxTotal")));
config.setMaxIdle(Integer.parseInt(pro.getProperty("maxIdle")));
//實例化JedisPool
jedisPool = new JedisPool(config,pro.getProperty("host"),Integer.parseInt(pro.getProperty("port")));
}
/** * 獲取鏈接 */
public static Jedis getJedis(){
return jedisPool.getResource();
}
}
複製代碼
若是文章中有什麼不足,或者錯誤的地方,歡迎你們留言分享想法,感謝朋友們的支持!
若是能幫到你的話,那就來關注我吧!若是您更喜歡微信文章的閱讀方式,能夠關注個人公衆號
在這裏的咱們素不相識,卻都在爲了本身的夢而努力 ❤
一個堅持推送原創開發技術文章的公衆號:理想二旬不止