Redis是一個(gè)開源,高級(jí)的鍵值存儲(chǔ)和一個(gè)適用的解決方案,用于構(gòu)建高性能,可擴(kuò)展的Web應(yīng)用程序。本文將概要介紹Redis的特性和語法,并以實(shí)例代碼的形式介紹如何通過Jedis在java語言環(huán)境下控制Redis,幫助各位讀者快速入門。
NoSQL概述
Redis是NoSQL數(shù)據(jù)庫的代表之一,那什么是NoSQL?
NoSQL = not only SQL,即非關(guān)系型數(shù)據(jù)庫。
Why NoSQL?
和傳統(tǒng)的關(guān)系型數(shù)據(jù)庫相比,NoSQL具有以下的優(yōu)勢(shì):
- High Performance:高并發(fā)讀寫;
- Huge Storage: 海量數(shù)據(jù)的高效存儲(chǔ)和訪問;
- High Scalability & High Availability:高可擴(kuò)展和高可用性
NoSQL的分類:
- Key-Value,如Redis,快速查詢,但是數(shù)據(jù)存儲(chǔ)缺少結(jié)構(gòu)化;
- 列存儲(chǔ),如HBase, 擴(kuò)展性強(qiáng),查找速度快,但是功能局限;
- 文檔數(shù)據(jù)庫,如MongoDB,數(shù)據(jù)格式靈活,查詢性能不高,缺少統(tǒng)一的查詢語法;
- 圖形數(shù)據(jù)庫,如InfoGrid,基于圖的算法,但是不容易做分布式的查詢;
Redis概述
Redis是一個(gè)開源,高性能的鍵值對(duì)數(shù)據(jù)庫, 其優(yōu)點(diǎn)包括:
- 異常快 :Redis非??欤棵肟蓤?zhí)行大約110000次的設(shè)置(SET)操作,每秒大約可執(zhí)行81000次的讀取/獲取(GET)操作。
- 支持豐富的數(shù)據(jù)類型 :Redis支持開發(fā)人員常用的大多數(shù)數(shù)據(jù)類型,例如列表,集合,排序集和散列等等。這使得Redis很容易被用來解決各種問題,因?yàn)槲覀冎滥男﹩栴}可以更好使用地哪些數(shù)據(jù)類型來處理解決。
- 操作具有原子性 : 所有Redis操作都是原子操作,這確保如果兩個(gè)客戶端并發(fā)訪問,Redis服務(wù)器能接收更新的值。
-
多實(shí)用工具 : Redis是一個(gè)多實(shí)用工具,可用于多種用例,如:
- 緩存;
- 任務(wù)隊(duì)列;
- 網(wǎng)站統(tǒng)計(jì);
- 數(shù)據(jù)過期處理;
- 應(yīng)用排行榜;
- 分布式集群的Session分離;
Redis與其他鍵值存儲(chǔ)系統(tǒng)
Redis是鍵值數(shù)據(jù)庫系統(tǒng)的不同進(jìn)化路線,它的值可以包含更復(fù)雜的數(shù)據(jù)類型,可在這些數(shù)據(jù)類型上定義原子操作。
Redis是一個(gè)內(nèi)存數(shù)據(jù)庫,但在磁盤數(shù)據(jù)庫上是持久的,因此它代表了一個(gè)不同的權(quán)衡,在這種情況下,在不能大于存儲(chǔ)器(內(nèi)存)的數(shù)據(jù)集的限制下實(shí)現(xiàn)非常高的寫和讀速度。
內(nèi)存數(shù)據(jù)庫的另一個(gè)優(yōu)點(diǎn)是,它與磁盤上的相同數(shù)據(jù)結(jié)構(gòu)相比,復(fù)雜數(shù)據(jù)結(jié)構(gòu)在內(nèi)存中存儲(chǔ)表示更容易操作。 因此,Redis可以做很少的內(nèi)部復(fù)雜性。
Redis的安裝和使用
Redis的安裝是否簡(jiǎn)單,在Ubuntu上安裝Redis,打開終端并鍵入以下命令即可
sudo apt-get update
sudo apt-get install redis-server
啟動(dòng)服務(wù)器:redis-server
啟動(dòng)客戶端:redis-cli
如果是Windows環(huán)境下,則參照以下文章:
http://download.csdn.net/download/fengxinyixiao/9860813
http://blog.csdn.net/joyhen/article/details/47358999
Jedis入門
Jedis是Redis官網(wǎng)首選的Java客戶端開發(fā)包.

其GItHub地址為:
https://github.com/xetorthio/jedis
在Maven中,添加如下依賴即可使用:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
以下是官網(wǎng)是上給出的示例代碼,連接本地Redis,進(jìn)行操作.
@Test
public void ConnectionTest(){
//1. Connecting to Redis server on localhost
Jedis jedis = new Jedis("localhost");
System.out.println("Connection to server sucessfully");
//2. set the data in redis string
jedis.set("username", "Roxin");
//3. Get the stored data and print it
System.out.println("Stored string in redis:: "+ jedis.get("username"));
//4. Close the Redis connection;
jedis.close();
}
其中通過調(diào)用set方法來設(shè)置鍵值對(duì),通過get方法獲取鍵值對(duì)。
除此之外,Jedis還提供連接池的方式控制連接
@Test
public void ConnectionPoolTest(){
//連接池設(shè)定
JedisPoolConfig config = new JedisPoolConfig();
//設(shè)定最大連接數(shù)
config.setMaxTotal(30);
//設(shè)置最大空閑連接數(shù)
config.setMaxIdle(10);
//創(chuàng)建連接池
JedisPool jedisPool = new JedisPool(config, "127.0.0.1");
//獲得服務(wù)資源
Jedis jedis = jedisPool.getResource();
jedis.select(1);
jedis.set("username", "Roxin By Jedis Pool");
System.out.println(jedis.get("username"));
jedis.close();
jedisPool.close();
}
Redis的數(shù)據(jù)類型
Redis中的數(shù)據(jù)類型有:
- 字符串(String)
- 列表(list)
- 有序集合(sorted set)
- 散列(hash)
- 集合(set)
無論哪種數(shù)據(jù)類型都需要為其設(shè)定鍵值Key,設(shè)置Key的注意點(diǎn):
- 不要太長(zhǎng)(<1024字節(jié));
- 不要太短,有可讀性;
- 統(tǒng)一命名規(guī)范;
String
Redis中的字符串是一個(gè)字節(jié)序列。Redis中的字符串是二進(jìn)制安全的,這意味著它們的長(zhǎng)度不由任何特殊的終止字符決定。因此,可以在一個(gè)字符串中存儲(chǔ)高達(dá)512兆字節(jié)的任何內(nèi)容。
除了上面提到的set/get方法,還有其他命令如下表:
| 序號(hào) | 命令 | 說明 |
|---|---|---|
| 1 | SET key value | 此命令設(shè)置指定鍵的值。 |
| 2 | GET key | 獲取指定鍵的值。 |
| 3 | GETRANGE key start end | 獲取存儲(chǔ)在鍵上的字符串的子字符串。 |
| 4 | GETSET key value | 設(shè)置鍵的字符串值并返回其舊值。 |
| 5 | GETBIT key offset | 返回在鍵處存儲(chǔ)的字符串值中偏移處的位值 |
| 6 | MGET key1 [key2..] | 獲取所有給定鍵的值 |
| 7 | SETBIT key offset value | 存儲(chǔ)在鍵上的字符串值中設(shè)置或清除偏移處的位 |
| 8 | SETEX key seconds value | 使用鍵和到期時(shí)間來設(shè)置值 |
| 9 | SETNX key value | 設(shè)置鍵的值,僅當(dāng)鍵不存在時(shí) |
| 10 | SETRANGE key offset value | 在指定偏移處開始的鍵處覆蓋字符串的一部分 |
| 11 | STRLEN key | 獲取存儲(chǔ)在鍵中的值的長(zhǎng)度 |
| 12 | MSET key value [key value …] | 為多個(gè)鍵分別設(shè)置它們的值 |
| 13 | MSETNX key value [key value …] | 為多個(gè)鍵分別設(shè)置它們的值,僅當(dāng)鍵不存在時(shí) |
| 14 | PSETEX key milliseconds value | 設(shè)置鍵的值和到期時(shí)間(以毫秒為單位) |
| 15 | INCR key | 將鍵的整數(shù)值增加1 |
| 16 | INCRBY key increment | 將鍵的整數(shù)值按給定的數(shù)值增加 |
| 17 | INCRBYFLOAT key increment | 將鍵的浮點(diǎn)值按給定的數(shù)值增加 |
| 18 | DECR key | 將鍵的整數(shù)值減1 |
| 19 | DECRBY key decrement | 按給定數(shù)值減少鍵的整數(shù)值 |
| 20 | APPEND key value | 將指定值附加到鍵 |
Hash
相當(dāng)于Map,在Redis中,每個(gè)哈希(散列)可以存儲(chǔ)多達(dá)4億個(gè)鍵-值對(duì)。
Jedis示例代碼如下
@Test
public void HashTest(){
Jedis jedis = jedisPool.getResource();
String hashKey = "hashKey";
//hset設(shè)置一個(gè)鍵值對(duì)
jedis.hset(hashKey,"user","Roxin");
HashMap<String, String> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.put("field"+i,"value"+i);
}
//設(shè)置多個(gè)鍵值對(duì)
jedis.hmset(hashKey,map);
//獲得鍵值對(duì)的個(gè)數(shù)
Long hlen = jedis.hlen(hashKey);
System.out.println("Hash Size in redis:: "+hlen);
assert hlen==11;
//得到全部鍵值對(duì)
List<String> user = jedis.hmget(hashKey, "user");
System.out.println("Stored string in redis:: "+ user);
assert user.get(0).equals("Roxin");
//刪除鍵值
jedis.del(hashKey);
jedis.close();
}
Redis關(guān)于Hash類型的常見命令如下表:
| 序號(hào) | 命令 | 說明 |
|---|---|---|
| 1 | HDEL key field2 [field2] | 刪除一個(gè)或多個(gè)哈希字段。 |
| 2 | HEXISTS key field | 判斷是否存在散列字段。 |
| 3 | HGET key field | 獲取存儲(chǔ)在指定鍵的哈希字段的值。 |
| 4 | HGETALL key | 獲取存儲(chǔ)在指定鍵的哈希中的所有字段和值 |
| 5 | HINCRBY key field increment | 將哈希字段的整數(shù)值按給定數(shù)字增加 |
| 6 | HINCRBYFLOAT key field increment | 將哈希字段的浮點(diǎn)值按給定數(shù)值增加 |
| 7 | HKEYS key | 獲取哈希中的所有字段 |
| 8 | HLEN key | 獲取散列中的字段數(shù)量 |
| 9 | HMGET key field1 [field2] | 獲取所有給定哈希字段的值 |
| 10 | HMSET key field1 value1 [field2 value2 ] | 為多個(gè)哈希字段分別設(shè)置它們的值 |
| 11 | HSET key field value | 設(shè)置散列字段的字符串值 |
| 12 | HSETNX key field value | 僅當(dāng)字段不存在時(shí),才設(shè)置散列字段的值 |
| 13 | HVALS key | 獲取哈希中的所有值 |
列表list
Redis列表只是字符串列表,按插入順序排序??梢栽诹斜淼念^部或尾部添加Redis列表中的元素。
列表的最大長(zhǎng)度為2^32 - 1個(gè)元素(即4294967295,每個(gè)列表可存儲(chǔ)超過40億個(gè)元素)。
Jedis中示例代碼如下
@Test
public void ListTest(){
Jedis jedis = jedisPool.getResource();
String listKey = "LISTKEY";
for (int i = 0; i < 10; i++) {
//從頭插入一個(gè)元素
jedis.lpush(listKey,"L-value");
}
List<String> list = jedis.lrange(listKey, 0, -1);//從第一個(gè)到最后一個(gè),負(fù)數(shù)代表倒數(shù)第幾個(gè)
assert list.size() == 10;
assert "L-value".equals(jedis.rpop(listKey));//從尾部取出一個(gè)元素
assert 9==jedis.llen(listKey);
jedis.rpush(listKey,"R-valure");//從尾部加入一個(gè)元素
jedis.lrem(listKey,2,"L-value");//刪除從左數(shù)2兩個(gè)"L-value"元素
jedis.lrem(listKey,0,"L-value"); //0表示刪除全部"L-value"元素
assert "R-valure".equals(jedis.lpop(listKey));//從頭部加入一個(gè)元素
jedis.del(listKey);
jedis.close();
}
Redis中關(guān)于list的命令如下表:
| 序號(hào) | 命令 | 說明 |
|---|---|---|
| 1 | BLPOP key1 [key2 ] timeout | 刪除并獲取列表中的第一個(gè)元素,或阻塞,直到有一個(gè)元素可用 |
| 2 | BRPOP key1 [key2 ] timeout | 刪除并獲取列表中的最后一個(gè)元素,或阻塞,直到有一個(gè)元素可用 |
| 3 | BRPOPLPUSH source destination timeout | 從列表中彈出值,將其推送到另一個(gè)列表并返回它; 或阻塞,直到一個(gè)可用 |
| 4 | LINDEX key index | 通過其索引從列表獲取元素 |
| 5 | LINSERT key BEFORE/AFTER pivot value | 在列表中的另一個(gè)元素之前或之后插入元素 |
| 6 | LLEN key | 獲取列表的長(zhǎng)度 |
| 7 | LPOP key | 刪除并獲取列表中的第一個(gè)元素 |
| 8 | LPUSH key value1 [value2] | 將一個(gè)或多個(gè)值添加到列表 |
| 9 | LPUSHX key value | 僅當(dāng)列表存在時(shí),才向列表添加值 |
| 10 | LRANGE key start stop | 從列表中獲取一系列元素 |
| 11 | LREM key count value | 從列表中刪除元素 |
| 12 | LSET key index value | 通過索引在列表中設(shè)置元素的值 |
| 13 | LTRIM key start stop | 修剪列表的指定范圍 |
| 14 | RPOP key | 刪除并獲取列表中的最后一個(gè)元素 |
| 15 | RPOPLPUSH source destination | 刪除列表中的最后一個(gè)元素,將其附加到另一個(gè)列表并返回 |
| 16 | RPUSH key value1 [value2] | 將一個(gè)或多個(gè)值附加到列表 |
| 17 | RPUSHX key value | 僅當(dāng)列表存在時(shí)才將值附加到列表 |
需要特別說明下:
rpoplpush source destination 刪除列表中的最后一個(gè)元素,將其附加到另一個(gè)列表并返回,在消息隊(duì)列中,可以用于消息備份:當(dāng)消息被發(fā)布后,一個(gè)消息從主消息隊(duì)列中被取出,被放入到緩存隊(duì)列中,當(dāng)確認(rèn)發(fā)生成功之后,再將其徹底刪除,如果發(fā)送不成功,就恢復(fù)該消息。

Set
Redis集合是唯一字符串的無序集合。 唯一值表示集合中不允許鍵中有重復(fù)的數(shù)據(jù)。
在Redis中設(shè)置添加,刪除和測(cè)試成員的存在(恒定時(shí)間O(1),而不考慮集合中包含的元素?cái)?shù)量)。列表的最大長(zhǎng)度為2^32 - 1個(gè)元素(即4294967295,每組集合超過40億個(gè)元素)。
存儲(chǔ)Set的使用場(chǎng)景:
- 跟蹤唯一性數(shù)據(jù)
- 用于維護(hù)數(shù)據(jù)對(duì)象之間的關(guān)聯(lián)關(guān)系;
Jedis的代碼示例:
@Test
public void SetTest(){
Jedis jedis = jedisPool.getResource();
String setKey1 = "SETKEY-1";
for (int i = 0; i < 10; i++) {
//添加一個(gè)元素
jedis.sadd(setKey1,"value-"+i);
}
assert 10 == jedis.scard(setKey1); //獲得元素個(gè)數(shù)
jedis.sadd(setKey1,"value-1");//添加重復(fù)的元素將失效
assert 10 == jedis.scard(setKey1);
String s= jedis.srandmember(setKey1);//隨機(jī)獲取一個(gè)元素
assert jedis.sismember(setKey1,s);//是否為集合成員
String setKey2 = "SETKEY-2";
for (int i = 1; i < 11; i++) {
jedis.sadd(setKey2,"value-"+i);
}
assert jedis.sdiff(setKey1,setKey2).size() == 1;//補(bǔ)集
assert jedis.sinter(setKey1,setKey2).size() == 9;//交集
assert jedis.sunion(setKey1,setKey2).size() == 11;//并集
jedis.del(setKey1,setKey2);
jedis.close();
}
Redis中關(guān)于Set的命令如下表:
| 序號(hào) | 命令 | 說明 |
|---|---|---|
| 1 | SADD key member1 [member2] | 將一個(gè)或多個(gè)成員添加到集合 |
| 2 | SCARD key | 獲取集合中的成員數(shù) |
| 3 | SDIFF key1 [key2] | 減去多個(gè)集合 |
| 4 | SDIFFSTORE destination key1 [key2] | 減去多個(gè)集并將結(jié)果集存儲(chǔ)在鍵中 |
| 5 | SINTER key1 [key2] | 相交多個(gè)集合 |
| 6 | SINTERSTORE destination key1 [key2] | 交叉多個(gè)集合并將結(jié)果集存儲(chǔ)在鍵中 |
| 7 | SISMEMBER key member | 判斷確定給定值是否是集合的成員 |
| 8 | SMOVE source destination member | 將成員從一個(gè)集合移動(dòng)到另一個(gè)集合 |
| 9 | SPOP key | 從集合中刪除并返回隨機(jī)成員 |
| 10 | SRANDMEMBER key [count] | 從集合中獲取一個(gè)或多個(gè)隨機(jī)成員 |
| 11 | SREM key member1 [member2] | 從集合中刪除一個(gè)或多個(gè)成員 |
| 12 | SUNION key1 [key2] | 添加多個(gè)集合 |
| 13 | SUNIONSTORE destination key1 [key2] | 添加多個(gè)集并將結(jié)果集存儲(chǔ)在鍵中 |
| 14 | SSCAN key cursor [MATCH pattern] [COUNT count] | 遞增地迭代集合中的元素 |
Sorted-Set
Redis可排序集合類似于Redis集合,是不重復(fù)的字符集合。 不同之處在于,排序集合的每個(gè)成員都與分?jǐn)?shù)相關(guān)聯(lián),這個(gè)分?jǐn)?shù)用于按最小分?jǐn)?shù)到最大分?jǐn)?shù)來排序的排序集合。雖然成員是唯一的,但分?jǐn)?shù)值可以重復(fù)。
Sorted-Set的使用場(chǎng)景:
- 大型在線游戲的積分排名;
- 構(gòu)建索引數(shù)據(jù);
Jedis中的示例:
@Test
public void SortedSetTest(){
Jedis jedis = jedisPool.getResource();
String sortedSetKey = "SORTEDSETKEY";
for (int i = 0; i < 10; i++) {
//添加一個(gè)元素
jedis.zadd(sortedSetKey,i*10,"v-"+i);
}
assert 10 == jedis.zcard(sortedSetKey);//獲得集合中元素個(gè)數(shù)
assert 20 == (jedis.zscore(sortedSetKey,"v-2"));//獲得集合中元素對(duì)應(yīng)的分?jǐn)?shù)
Set<String> set = jedis.zrange(sortedSetKey, 0, -2);//從第一個(gè)到倒數(shù)第二個(gè)
assert 9 == set.size() ;
assert !set.contains("v-9");
jedis.zincrby(sortedSetKey,20,"v-1");//讓元素的分?jǐn)?shù)增長(zhǎng)20
assert 30 == jedis.zscore(sortedSetKey,"v-1");
assert 3 == jedis.zcount(sortedSetKey,20,30);//獲得分?jǐn)?shù)段中元素個(gè)數(shù)
jedis.del(sortedSetKey);
jedis.close();
}
Keys的通用操作
Jedis中關(guān)于鍵值操作的實(shí)例:
@Test
public void KeyTest(){
Jedis jedis = jedisPool.getResource();
String key = "TESTKEY-1";
String key2 = "TESTKEY-2";
jedis.set(key2,"");//設(shè)置鍵值
jedis.rename(key2,key);//鍵值重命名
System.out.println("Key Type:"+jedis.type(key));//鍵值的類型
assert jedis.exists(key);//鍵值是否存在
jedis.expire(key,1);//設(shè)置鍵值過期時(shí)間
assert 1 == jedis.ttl(key);//查看鍵值過期時(shí)間
try {
Thread.sleep(2000);//睡眠2s
} catch (InterruptedException e) {
e.printStackTrace();
}
assert !jedis.exists(key);//鍵值已過期,不存在
}
Redis中關(guān)于鍵值的其他命令:
| 編號(hào) | 命令 | 描述 |
|---|---|---|
| 1 | DEL key | 此命令刪除一個(gè)指定鍵(如果存在) |
| 2 | DUMP key | 此命令返回存儲(chǔ)在指定鍵的值的序列化版本 |
| 3 | EXISTS key | 此命令檢查鍵是否存在 |
| 4 | EXPIRE key seconds | 設(shè)置鍵在指定時(shí)間秒數(shù)之后到期/過期 |
| 5 | EXPIREAT key timestamp | 設(shè)置在指定時(shí)間戳之后鍵到期/過期。這里的時(shí)間是Unix時(shí)間戳格式 |
| 6 | PEXPIRE key milliseconds | 設(shè)置鍵的到期時(shí)間(以毫秒為單位) |
| 7 | PEXPIREAT key milliseconds-timestamp | 以Unix時(shí)間戳形式來設(shè)置鍵的到期時(shí)間(以毫秒為單位) |
| 8 | KEYS pattern | 查找與指定模式匹配的所有鍵 |
| 9 | MOVE key db | 將鍵移動(dòng)到另一個(gè)數(shù)據(jù)庫 |
| 10 | PERSIST key | 刪除指定鍵的過期時(shí)間,得永生 |
| 11 | PTTL key | 獲取鍵的剩余到期時(shí)間 |
| 12 | RANDOMKEY | 從Redis返回一個(gè)隨機(jī)的鍵 |
| 13 | RENAME key newkey | 更改鍵的名稱 |
| 14 | PTTL key | 獲取鍵到期的剩余時(shí)間(以毫秒為單位) |
| 15 | RENAMENX key newkey | 如果新鍵不存在,重命名鍵 |
| 16 | TYPE key | 返回存儲(chǔ)在鍵中的值的數(shù)據(jù)類型 |
KEYS pattern 查找與指定模式匹配的所有鍵:
- keys * 查看所有的key;
- keys xx? 模糊匹配key;
Redis的特性
多數(shù)據(jù)
提供16個(gè)數(shù)據(jù)庫(0-15),默認(rèn)為0號(hào)數(shù)據(jù)庫,可是通過select index選擇。
事務(wù)
和關(guān)系型數(shù)據(jù)庫一樣,Redis也提供事務(wù)性操作:
DISCARD 丟棄在MULTI之后發(fā)出的所有命令(放棄事務(wù),回滾)- EXEC 執(zhí)行MULTI后發(fā)出的所有命令(提交事務(wù))
- MULTI 標(biāo)記事務(wù)塊的開始(開始事務(wù))
- UNWATCH 取消 WATCH 命令對(duì)所有 key 的監(jiān)視。
- WATCH key [key …] 監(jiān)視給定的鍵以確定MULTI / EXEC塊的執(zhí)行
Redis中示例代碼如下:
@Test
public void TransactionTest(){
//獲得服務(wù)資源
Jedis jedis = jedisPool.getResource();
jedis.select(1);
Transaction transaction = jedis.multi();//開啟事務(wù)
transaction.set("username", "Roxin in transaction1");
System.out.println(transaction.get("username"));
transaction.exec();//提交事務(wù)
System.out.println(jedis.get("username"));
transaction = jedis.multi();//開啟事務(wù)
transaction.set("username", "Roxin in transaction2");
System.out.println(transaction.get("username"));
transaction.discard();//撤銷事務(wù)
System.out.println(jedis.get("username"));
jedis.close();
}
Redis持久化
Redis是一個(gè)內(nèi)存數(shù)據(jù)庫,但在磁盤數(shù)據(jù)庫上是持久化的,持久化的方式分為兩種:
- RDB:默認(rèn)方式,定時(shí)將內(nèi)存數(shù)據(jù)集快照寫入磁盤;
- AOF:以日志的方式,記錄所有操作;
RDB
優(yōu)勢(shì)
- 數(shù)據(jù)只存在一個(gè)文件中,便于數(shù)據(jù)歸檔和整理;
- 多線程啟動(dòng),性能好;
劣勢(shì)
- 如果在兩次快照寫操作之間出現(xiàn)問題,將無法回復(fù)期間的數(shù)據(jù);
- 多線程啟動(dòng)的時(shí)候,可能會(huì)有停頓;
配置文件為Redis按照目錄下的 redis.conf:

這是配置文件設(shè)置內(nèi)存快照寫入磁盤的條件
# 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
數(shù)據(jù)文件被定義為dump.rdb,保存路徑為Redis的按照路徑。
# The filename where to dump the DB
dbfilename dump.rdb
# The working directory.
#
# The DB will be written inside this directory, with the filename specified
# above using the 'dbfilename' configuration directive.
#
# The Append Only File will also be created inside this directory.
#
# Note that you must specify a directory here, not a file name.
dir ./

AOF
優(yōu)勢(shì):
-
更高的數(shù)據(jù)安全性,有三種數(shù)據(jù)同步策略:
- 每秒同步,效率高,但是在一秒間隔內(nèi)斷電,未同步的數(shù)據(jù)會(huì)丟失;
- 每次修改同步,性能低,但是安全;
- 不同步;
日志是追加(append)模式,即使有宕機(jī),也不會(huì)用問題。 如果是數(shù)據(jù)寫入一半出現(xiàn)問題,可以使用redis-check-aof,恢復(fù)數(shù)據(jù)一致;
日志自動(dòng)重寫,以防止日志過大;
日志格式清楚明了,可用于數(shù)據(jù)重建;
劣勢(shì):
- 文件要更大;
- 運(yùn)行效率更低;
配置文件中關(guān)于AOF的配置:

默認(rèn)不使用;
日志文件為 appendonly.aof
# The name of the append only file (default: "appendonly.aof")
appendfilename "appendonly.aof"
上面提高的三種同步策略;
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is "everysec",If unsure, use "everysec".
# appendfsync always
appendfsync everysec
# appendfsync no