一. 基本數(shù)據(jù)類型
String(字符串)
string是redis最基本的類型,一個key對應(yīng)一個value。
string類型是二進制安全的。意思是redis的string可以包含任何數(shù)據(jù)。比如jpg圖片或者序列化的對象 。
string類型是Redis最基本的數(shù)據(jù)類型,一個鍵最大能存儲512MB。
SET key value
GET key
Redis 集合(Set)
Redis的Set是string類型的無序集合。集合成員是唯一的,這就意味著集合中不能出現(xiàn)重復(fù)的數(shù)據(jù)。
Redis 中 集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。
集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。
SADD key value
SMEMBERS key
Redis 有序集合(sorted set)
Redis 有序集合和集合一樣也是string類型元素的集合,且不允許重復(fù)的成員。
不同的是每個元素都會關(guān)聯(lián)一個double類型的分?jǐn)?shù)。redis正是通過分?jǐn)?shù)來為集合中的成員進行從小到大的排序。有序集合的成員是唯一的,但分?jǐn)?shù)(score)卻可以重復(fù)。
集合是通過哈希表實現(xiàn)的,所以添加,刪除,查找的復(fù)雜度都是O(1)。 集合中最大的成員數(shù)為 232 - 1 (4294967295, 每個集合可存儲40多億個成員)。
ZADD key score value
ZRANGE key start stop WITHSCORES
Redis 列表(List)
Redis列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導(dǎo)列表的頭部(左邊)或者尾部(右邊)
一個列表最多可以包含 232 - 1 個元素 (4294967295, 每個列表超過40億個元素)。
LPUSH key value
LRANGE key start stop
Redis 哈希(Hash)
Redis hash 是一個string類型的field和value的映射表,hash特別適合用于存儲對象。
Redis 中每個 hash 可以存儲 232 - 1 鍵值對(40多億)。
HMSET key filed1 value1 filed2 value2
HGETALL key
二. 保證操作的原子性
watch機制(無法保證原子性)
127.0.0.1:6379[1]> MULTI
OK
127.0.0.1:6379[1]> set key 1
QUEUED
127.0.0.1:6379[1]> set key2 nn
QUEUED
127.0.0.1:6379[1]> INCR key2
QUEUED
127.0.0.1:6379[1]> EXEC
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
命令 “INCR key2” 把字符串自增,被成功加入隊列,但是最后執(zhí)行的時候報錯,然而前兩個命令成功執(zhí)行了,所以沒有保證原子性。
lua腳本
Lua 嵌入 Redis 優(yōu)勢:
減少網(wǎng)絡(luò)開銷: 不使用 Lua 的代碼需要向 Redis 發(fā)送多次請求, 而腳本只需一次即可, 減少網(wǎng)絡(luò)傳輸;
原子操作: Redis 服務(wù)器會單線程原子性執(zhí)行 lua 腳本,保證 lua 腳本在處理的過程中不會被任意其它請求打斷;
復(fù)用: 腳本會永久保存 Redis 中, 其他客戶端可繼續(xù)使用.
eg:通過腳本實現(xiàn)自乘運算
local curVal = redis.call("get", KEYS[1])
if curVal == false then
curVal = 0
else
curVal = tonumber(curVal)
end
curVal = curVal * tonumber(ARGV[1])
redis.call("set", KEYS[1], curVal)
return curVal
script load 'local curVal = redis.call("get", KEYS[1]); if curVal == false then curVal = 0 else curVal = tonumber(curVal) end; curVal = curVal * tonumber(ARGV[1]); redis.call("set", KEYS[1], curVal); return curVal'
be4f93d8a5379e5e5b768a74e77c8a4eb0434441
evalsha be4f93d8a5379e5e5b768a74e77c8a4eb0434441 1 foo 5
三.Spring redis cache
1.配置RedisCacheManager
設(shè)置緩存的名稱是否作為key的前綴
設(shè)置key的失效時間
2. @Cacheable、@CachePut、@CacheEvict 注釋介紹
@Cacheable 的作用:主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存
表 1. @Cacheable 作用和配置方法
| @Cacheable 主要的參數(shù) | 說明 | 舉例 |
|---|---|---|
| value | 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個 | @Cacheable(value=”mycache”) 或者 @Cacheable(value={”cache1”,”cache2”} |
| key | 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進行組合 | @Cacheable(value=”testcache”,key=”#userName”) |
| condition | 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存 | @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
@CachePut 的作用:主要針對方法配置,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存,和 @Cacheable 不同的是,它每次都會觸發(fā)真實方法的調(diào)用
表 2. @CachePut 作用和配置方法
| @CachePut 參數(shù)說明 | 說明 | 舉例 |
|---|---|---|
| value | 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個 | @Cacheable(value=”mycache”) 或者 @Cacheable(value{”cache1”,”cache2”} |
| key | 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進行組合 | @Cacheable(value=”testcache”,key=”#userName”) |
| condition | 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存 | @Cacheable(value=”testcache”,condition=”#userName.length()>2”) |
@CachEvict 的作用:主要針對方法配置,能夠根據(jù)一定的條件對緩存進行清空
表 3. @CacheEvict 作用和配置方法
| @CacheEvict主要的參數(shù) | 說明 | 舉例 |
|---|---|---|
| value | 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個 | @CachEvict(value=”mycache”) 或者 @CachEvict(value={”cache1”,”cache2”} |
| key | 緩存的 key,可以為空,如果指定要按照 SpEL 表達(dá)式編寫,如果不指定,則缺省按照方法的所有參數(shù)進行組合 | @CachEvict(value=”testcache”,key=”#userName”) |
| condition | 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才清空緩存 | @CachEvict(value=”testcache”,condition=”#userName.length()>2”) |
| allEntries | 是否清空所有緩存內(nèi)容,缺省為 false,如果指定為 true,則方法調(diào)用后將立即清空所有緩存 | @CachEvict(value=”testcache”,allEntries=true) |
| beforeInvocation | 是否在方法執(zhí)行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執(zhí)行的時候就清空緩存,缺省情況下,如果方法執(zhí)行拋出異常,則不會清空緩存 | @CachEvict(value=”testcache”,beforeInvocation=true) |
三.緩存key的生成策略問題
1. If no params are given, return SimpleKey.EMPTY.
2. If only one param is given, return that instance.
3. If more the one param is given, return a SimpleKey containing all parameters.
問題1.如果redisTemplate設(shè)置了template.setKeySerializer(new StringRedisSerializer()),會出現(xiàn)key的類型轉(zhuǎn)換異常
問題2.不同包下的方法參數(shù)相同時,key沖突
解決:重寫keyGenerator()
四.redis集群搭建
集群模式下,redis各個節(jié)點通過請求轉(zhuǎn)發(fā),找到真正的槽