前言
昨天和室友去包夜戏羽,玩了一晚上的
LOL
担神,跪了一整夜,但是很開心始花。從S1
末開始玩LOL
的我妄讯,到現(xiàn)在還是青銅孩锡,真是菜的摳腳。最近負能力滿滿的捞挥,唯有睡覺和學(xué)習(xí)才可解憂愁浮创。今天也看了慕課網(wǎng)上面的《Redis
入門》,來記一下學(xué)習(xí)筆記砌函。(寫這篇文章開頭的時候應(yīng)該是一個星期之前)
NoSQL概述
NoSQL
就是Not Only SQL
的意思斩披,是非關(guān)系型數(shù)據(jù)庫。-
為什么需要
NoSQL
?High performance
- 高并發(fā)讀寫Huge Storage
- 海量數(shù)據(jù)的高效率存儲和訪問High Scalability & High Availability
- 高可擴展性和高可用性
-
NoSQL數(shù)據(jù)庫的四大分類
鍵值(
Key - Value
)存儲:優(yōu)點是快速查詢讹俊,缺點存儲的數(shù)據(jù)缺少結(jié)構(gòu)化垦沉。列存儲:優(yōu)點是查詢比較快,擴展性比較強仍劈,缺點是功能相對局限厕倍。
文檔數(shù)據(jù)庫:對應(yīng)的產(chǎn)品就是
MongoDB
。對數(shù)據(jù)結(jié)構(gòu)要求不是特別嚴格贩疙,查詢性能不能特別高讹弯,缺少統(tǒng)一查詢的語法。圖形數(shù)據(jù)庫:優(yōu)點是利用圖結(jié)構(gòu)相關(guān)的算法这溅,缺點是需要對整個圖進行結(jié)算才能得出結(jié)果组民,不能作為分布式的解決方案。
- 現(xiàn)在來說說
NoSQL
的特點悲靴,美滋滋臭胜。- 易擴展
- 靈活的數(shù)據(jù)模型
- 高可用
- 大數(shù)據(jù)量,高性能
Redis的概述
-
高性能鍵值對數(shù)據(jù)庫癞尚,支持的鍵值數(shù)據(jù)類型:
字符串類型 -
String
列表類型 -
Set
有序集合類型 -
Sorted Set
散列類型 -
Hash
集合類型 -
List
-
Redis
的應(yīng)用場景緩存
任務(wù)隊列
網(wǎng)站訪問統(tǒng)計
應(yīng)用排行榜
分布式集群架構(gòu)中的session分離
Redis在Linux上的使用
可以看我這篇文章【Linux學(xué)習(xí)】 Redis常用的一些指令
Jedis的入門
- 我們要在
Java
平臺上使用redis
耸三,肯定需要Jedis
這個客戶端。首先在pom
文件中引入Jedis
的依賴
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
- 普通方式創(chuàng)建Jedis對象浇揩。
public void methodOne() {
Jedis jedis = new Jedis("100.64.84.47", 6379);
jedis.set("name", "cmazxiaoma");
String value = jedis.get("name");
System.out.println(value);
jedis.close();
}
- 通過線程安全的連接池來創(chuàng)建Jedis對象仪壮。
public void methodTwo() {
//獲得連接池的配置對象
JedisPoolConfig config = new JedisPoolConfig();
//設(shè)置最大連接數(shù)
config.setMaxTotal(30);
//設(shè)置最大空閑連接數(shù)
config.setMaxIdle(10);
//獲得連接池
JedisPool jedisPool = new JedisPool(config, "100.64.84.47", 6379);
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
String value = jedis.get("name");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
jedisPool.close();
}
}
}
- 編寫測試類。
public class JedisDemo1Test {
private JedisDemo1 demo;
@Before
public void setUp() {
demo = new JedisDemo1();
}
@Test
public void methodOne() throws Exception {
demo.methodOne();
}
@Test
public void methodTwo() throws Exception {
demo.methodTwo();
}
}
-
運行
Test Case
胳徽,測試成功积锅。
image.png -
我們在
Xshell
軟件,輸入get name
指令膜廊,也可以看到輸出cmazxiaoma
。
image.png
Redis的數(shù)據(jù)結(jié)構(gòu)
String
-
Key
定義的注意點:- 不要過長淫茵。
- 不要過短爪瓜。
- 統(tǒng)一的命名規(guī)范。
-
存儲
String
:- 二進制安全的匙瘪,存入和獲取的數(shù)據(jù)相同铆铆。
-
Value
最多可以容納的數(shù)據(jù)長度是512M
蝶缀。
-
存儲
String
常用的命令:-
賦值
image.png -
取值
image.png -
刪除
image.png 數(shù)值增減
-
如果屬性不存在的話,那么integer
類型默認為0
薄货。
如果name
屬性的值不能轉(zhuǎn)換成integer
類型翁都,那么會拋出ERR is not an integer or out of range
異常。
decr
指令也是一樣的谅猾。
- 擴展命令
incrby
柄慰、decrby
也是一樣的,很簡單税娜。
image.png
append
指令可以拼接字符串坐搔。
如果append key cmazxiaoma
。這個key
不存在的話敬矩,首先會創(chuàng)建這個key
概行,然后存入cmazxiaoma
內(nèi)容,接著輸出cmazxiaoma
弧岳。
Hash
-
賦值凳忙,可以使用
hset myhash key value
單一賦值、hmset myhash key value key value
多次賦值禽炬。
image.png -
取值涧卵,可以用
hget myhash key
單一取值、hmget myhash key key
多個取值瞎抛、hgetall
取出所有key
所對應(yīng)的值艺演。
image.png -
刪除 ,可以用
hdel myhash key
刪除單一的key
。
image.png
hdel myhash key key
刪除多個的key
桐臊。
del myhash
刪除myhash
中所有的key
胎撤。
-
數(shù)值增減,
hincrby myhash key 100
image.png -
使用
hexists myhash key
判斷key
是否在myhash
中存在断凶,存在返回1
伤提,不存在返回0
。
image.png -
hlen myhash
獲取myhash
中存在key
的數(shù)量认烁。
image.png -
hkeys myhash
獲取myhash
中所有的key
肿男。
image.png -
hvals myhash
獲取myhash
中所有的values
。
image.png
List
-
存儲list:
-
ArrayList
使用數(shù)組方式 -
LinkedList
使用雙向鏈表方式
-
-
兩端添加
- 使用
lpush a b c
命令在左端添加却嗡,那么c
肯定是在最左端舶沛。
image.png - 使用
rpush a b c
命令在右端添加,那么c
肯定是在最右端窗价。
image.png
- 使用
-
兩端彈出
- 使用
lpop mylist
彈出mylist
中頭部元素如庭、rpop mylist2
彈出mylist2
尾部中的元素。它們都是3
撼港。
image.png - 我們接著來查看
mylist
坪它、mylist2
骤竹。
image.png
- 使用
- 查看列表
- 使用
lrange mylist 0 5
來查看mylist
列表,mylist
插入的方式從頭結(jié)點開始添加的往毡,那么輸出肯定是321abc
蒙揣。
image.png - 使用
lrange mylist2 0 5
查看mylist2
列表,mylist2
插入的方式是從最右端添加的开瞭,那么輸出肯定是abc123
image.png
- 使用
-
獲取列表元素的個數(shù)
- 使用
llen mylist
命令
image.png
- 使用
-
擴展命令
-
使用
lpushx mylist x
懒震,使插入的元素在頭部位置。
image.png -
使用
rpushx mylist x
惩阶,使插入的元素在尾部位置挎狸。
image.png -
使用
lrem mylist count element
,count
代表是刪除的次數(shù)断楷,element
代表是需要刪除的元素锨匆。如果count > 0
代表刪除的方式從頭到尾,刪除count
個element
冬筒,count < 0
代表刪除的方式從尾到頭恐锣,刪除count
個element
。如果count = 0
舞痰,刪除mylist
中所有和element
相同的元素土榴。
image.png
image.png -
lrem mylist 2 test1
image.png -
lrem mylist -2 test1
image.png -
lrem mylist 0 cmazxiaoma
image.png -
在某一個下標位置插入元素。
lset mylist index element
image.png -
在目標元素之前插入指定的元素响牛。
linsert mylist before helloworl before_helloworld
image.png
image.png -
在目標元素之后插入指定的元素玷禽。
linsert mylist helloworld after after_helloworld
image.png -
彈出
mylist
中最后一個元素,并插入到mylist
中的頭部呀打。rpoplpush mylist mylist
image.png -
rpoplpush
使用場景
image.png
-
Set
和List
類型不同的是矢赁,Set
集合中不允許出現(xiàn)重復(fù)的元素。
- 添加/刪除元素
- 添加
sadd myset a b c
贬丛,如果我們重復(fù)添加相同的元素撩银,肯定是不成功的。比如sadd myset a
豺憔。
image.png - 刪除
srem myset a
额获,刪除myset
中的a
元素。
image.png - 查看
myset
中的元素恭应。smembers myset
image.png - 查看指定元素是否是
myset
中的成員抄邀。sismember myset a
,返回0
代表不存在昼榛,返回1
代表存在境肾。
image.png
- 添加
獲得集合中的元素,
smembers myset
-
集合中的差集運算,
sdiff myset2 myset
。myset2
中元素有b,c,d
准夷。myset
中元素有b,c
。它們之間的差集運算結(jié)果應(yīng)該為d
莺掠。
image.png-
集合中的交集運算衫嵌,
sinter myset2 myset
,應(yīng)該輸出cb
彻秆。
image.png -
集合中的并集運算楔绞,
sunion myset2 myse
t,應(yīng)該輸出cbd
唇兑。
image.png
-
-
擴展命令
-
scard myset
查看myset
有多少個元素酒朵。
image.png -
srandmember myset
隨機返回myset
中的一個元素。
image.png -
sdiffstore new_myset myset2 myset
把myset
和myset2
差集元素的結(jié)果存儲到new_myset
中扎附。(sinterstore
,sunionstore
也是一樣的用法)
image.png
-
-
Set使用場景
- 跟蹤一些唯一性的數(shù)據(jù)蔫耽。
- 用于維護數(shù)據(jù)對象之間的關(guān)聯(lián)關(guān)系。
SortedSet
SortedSet
中的成員在集合中的位置是有序的留夜。
-
添加元素
zadd mysort 70 cmazxiaoma 80 xiaoma 100 doudou
image.png -
獲得元素
-
zcard mysort
獲得mysort
中所有元素的個數(shù)
image.png -
獲得
mysort
中name
為cmazxiaoma
對應(yīng)的成績咙边。zscore mysort cmazxiaoma
image.png
-
-
刪除元素誓焦,
zrem mysort cmazxiaoma deli doudou xiaoma
image.png -
范圍查詢
zrange mysort 0 -1
,輸出的key
是按成績正序排列。
image.png-
如果輸出的數(shù)據(jù)項要帶上成績的話搞挣,指令應(yīng)該是
zrange mysort 0 -1 withscores
image.png -
如果輸出的數(shù)據(jù)項想按成績逆序排序,那么就應(yīng)該
zrevrange mysort 0 -1 withscores
image.png -
如果想按排名范圍進行刪除的話壹瘟,那么應(yīng)該
zremrangebyrank mysort 0 2
image.png -
如果想按成績范圍進行刪除的話阅签,那么應(yīng)該
zremrangebyscore mysort 0 10
。顧名思義刪除成績在0-10
之內(nèi)的數(shù)據(jù)項枕面。
image.png
-
-
擴展命令
-
查看分數(shù)在
0-10
之內(nèi)的學(xué)生信息愿卒,zrangebyscore mysort 0 10 withscores
image.png -
查看分數(shù)在
0-100
之內(nèi)且在第1
行-第2
行的學(xué)生信息。zrangebyscore mysort 0 100 withscores limit 0 2
image.png -
給
cmazxiaoma
的成績加100
分膊畴。zincrby mysort cmazxiaoma 100
image.png -
查看成績
0-10
之間的學(xué)生的個數(shù)掘猿。zcount mysort 0 10
image.png
-
-
Sorted Set
使用場景如大型在線游戲積分排行榜
構(gòu)建索引數(shù)據(jù)
Redis中的通用命令
-
key *
獲取所有redis中的key
image.png -
keys my*
獲取所有redis
中以my
開頭的key
image.png -
exists mylist
查看redis
中是否存在mylis
t,0
代表不存在唇跨,1
代表存在稠通。
image.png -
rename name new_name
給名字為name
的數(shù)據(jù)結(jié)構(gòu)重命名為new_name
image.png -
expire new_name 10
設(shè)置redis
中new_name
過期時間,通過ttl new_name
看到其距離過期的時間买猖。
image.png -
type mylist
改橘,可以查看mylist
對應(yīng)的數(shù)據(jù)結(jié)構(gòu)類型。
image.png
Redis的事務(wù)
-
Redis
相關(guān)的特性:多數(shù)據(jù)庫
Redis
事務(wù)
-
一個
Redis
最多可以提供16
個數(shù)據(jù)庫玉控,下標分別是0-15
飞主。客戶端默認連接的是第0
號數(shù)據(jù)。我們可以通過select index
來選擇數(shù)據(jù)庫碌识。
image.png -
我們想把第
0
號的數(shù)據(jù)庫中某些key
移動到第1
號數(shù)據(jù)庫里面碾篡,那么我們該怎么做呢。通過move cmazxiaoma_test_mayday_5 1
就可以完成筏餐。
image.png 我們可以通過
multi
开泽、exec
、discard
來完成事務(wù)操作魁瞪。事務(wù)執(zhí)行期間穆律,Redis
不會為其他客戶端提供任何服務(wù),以保證事務(wù)中的所有命令原子執(zhí)行导俘。multi
相當(dāng)于開啟事務(wù)峦耘,exec
相當(dāng)于提交,discard
相當(dāng)于回滾旅薄。-
首先我們在第一個客戶端進行如下操作辅髓。我們在第一個客戶端開啟了事務(wù),在事務(wù)中我們
incr num
2
次少梁,按理來說利朵,get num
應(yīng)該等于4
。
redis第一個客戶端.png -
我們在第二個客戶端輸入
get num
猎莲,發(fā)現(xiàn)num
還是2
绍弟。那么證明了我們的結(jié)論:事務(wù)執(zhí)行期間,Redis
不會為其他客戶端提供任何服務(wù)著洼,以保證事務(wù)中的所有命令原子執(zhí)行樟遣。
image.png -
如果我們在第一個客戶端提交了事務(wù)。
image.png -
接著我們在第二個客戶端
get num
身笤,發(fā)現(xiàn)可以num
的值得到了更新豹悬。
image.png -
我們可以演示一下回滾操作,首先
set user cmazxiaoma
液荸,接著開啟事務(wù)瞻佛,在事務(wù)中set user xiaoma
,然后進行回滾操作娇钱,發(fā)現(xiàn)get user
依然是cmazxiaoma
伤柄。
image.png
Redis的持久化
Redis
的性能體現(xiàn)在它把數(shù)據(jù)都保存在內(nèi)存當(dāng)中。我們把內(nèi)存中的數(shù)據(jù)同步到硬盤當(dāng)中的操作稱之為持久化文搂。
-
Redis
持久化方式:RDB
方式适刀,在指定的時間內(nèi),把內(nèi)存中的數(shù)據(jù)快照寫入到硬盤當(dāng)中煤蹭。AOF
方式笔喉,將以日志的形式記錄服務(wù)器所處理的每一個操作取视。當(dāng)Redis
服務(wù)器啟動之初,它會讀取該aof
文件常挚,會重新構(gòu)建我們的數(shù)據(jù)庫作谭。保證我們啟動之后,保證數(shù)據(jù)的完整性奄毡。無持久化丢早,我們可以通過配置禁止
Redis
服務(wù)器的持久化,我們認為Redis
就是緩存的一種機制了秧倾。同時使用。
-
RDB
:默認情況下傀缩,每隔一段時間
redis
服務(wù)器程序會自動對數(shù)據(jù)庫做一次遍歷那先,把內(nèi)存快照寫在一個叫做"dump.rdb"
的文件里,這個持久化機制叫做SNAPSHOT
赡艰。有了SNAPSHOT
后售淡,如果服務(wù)器宕機,重新啟動redis
服務(wù)器時慷垮,redis
會自動加載"dump.rdb"
,將數(shù)據(jù)庫狀態(tài)恢復(fù)上一次SNAPSHOT
的狀態(tài)揖闸。Redis
服務(wù)器初始化過程中,設(shè)定了定時時間料身,每隔一段時間就會觸發(fā)持久化操作汤纸,進入定時事件處理程序中,就會fork
出子進程來進行持久化操作芹血。Redis
服務(wù)器預(yù)設(shè)了save
指令贮泞,客戶端可要求服務(wù)器進程中斷服務(wù),執(zhí)行持久化操作幔烛。-
我們可以通過
vim /etc/redis.conf
打開配置文件啃擦,可以看到以下配置。
image.png -
同時我們還可以看到內(nèi)存快照輸出在
file
文件名饿悬。
image.png
優(yōu)缺點:
如果數(shù)據(jù)集很大令蛉,
RDB
相對于AOF
啟動效率很更高。如果想保證數(shù)據(jù)的高可用性狡恬,最大限度的避免數(shù)據(jù)的丟失珠叔,
RDB
將不是一個好的選擇。因為系統(tǒng)在定時持久化操作之前弟劲,還沒來得及在硬盤寫入數(shù)據(jù)就發(fā)生宕機的話运杭,就造成了數(shù)據(jù)的丟失。RDB
通過fork
出子線程來完成數(shù)據(jù)持久化操作函卒,如果當(dāng)數(shù)據(jù)集很大的時候辆憔,可能會導(dǎo)致服務(wù)器停止幾百ms
撇眯,或者幾s
。
AOF
(append only file
):-
對于
Redis
服務(wù)器而言虱咧,其缺省的機制是RDB
熊榛,如果需要使用AOF
,則需要修改appendonly no
改成appendonly yes
腕巡。Redis
在每一次收到數(shù)據(jù)修改的命令之后玄坦,都會將其追加到AOF
文件中。在Redis
下一次重新啟動時绘沉,需要加載AOF
文件中的信息來構(gòu)建最新的數(shù)據(jù)到內(nèi)存中煎楣。
image.png
image.png 可以記錄服務(wù)器的所有寫操作。在服務(wù)器重新啟動時车伞,會把所有的寫操作重新執(zhí)行一遍從而實現(xiàn)數(shù)據(jù)的備份择懂。當(dāng)寫操作集過大(比原有的數(shù)據(jù)集還大),
Redis
會重寫寫操作集另玖。帶來更好的數(shù)據(jù)安全性困曙,有
3
種同步策略,每秒同步谦去,每修改同步慷丽,不同步。 每秒同步也是異步完成的鳄哭,效率也非常高要糊。缺點是一旦系統(tǒng)發(fā)生宕機的現(xiàn)象,那么這一秒中的修改的數(shù)據(jù)就會發(fā)生丟失妆丘。每修改同步杨耙,我們可以視為同步持久化。每一次發(fā)生數(shù)據(jù)的變化飘痛,就會立即的記錄在磁盤珊膜,這種效率很低,但是很安全宣脉。采用
append
追加的模式车柠,就算系統(tǒng)發(fā)生宕機,也不會影響我們?nèi)罩疚募幸呀?jīng)存在的內(nèi)容塑猖。然而我們本次操作中竹祷,只寫入了一半數(shù)據(jù)就出現(xiàn)了系統(tǒng)崩潰的問題。在Redis下一次啟動之前羊苟,我們可以通過"redis-check-aof --fix <filename>"
命令來修復(fù)壞損的AOF
文件塑陵,解決數(shù)據(jù)一致性的問題。對于相同數(shù)量的數(shù)據(jù)集而言蜡励,
AOF
文件通常要大于RDB
文件令花。AOF
在運行效率上往往會慢于RDB
阻桅。
-
RDB
和AOF
的區(qū)別
前者是保存了數(shù)據(jù)本身,而后者是記錄了數(shù)據(jù)的變更兼都。
尾言
這篇文章最后在網(wǎng)吧完成的嫂沉,勿以善小而不為。