redis
是什么?
是完全開源免費的,用c語言編寫的,是一個單線程,高性能的(key/value)內存數據庫,基于內存運行并支持持久化的nosql數據庫
能干嘛?
主要是用來做緩存,但不僅僅只能做緩存,比如:redis的計數器生成分布式唯一主鍵,redis實現分布式鎖,隊列,會話緩存。
去哪下?
官網,也可以通過Linux yum直接下載安裝
怎么玩?
1.安裝
2.redis數據類型(api操作)
3.redis配置文件解析
4.redis的持久化
5.redis的事務
6.redis的發布訂閱
7.java客戶端操作(jedis)
redis的安裝
1.解壓
2.make
如果make報錯的話 大家就可以看一下是不是報沒有gcc的錯 如果是報沒有gcc的錯,那就要先安裝一個gcc
yum install gcc-c++
安裝好gcc之后最好執行一下make distclean 因為前面make的時候它執行了一些東西 要先把他清掉
3.make install
查看redis默認安裝位置
/usr/local/bin
redis設置外網訪問
1.注釋bind并且把protected-mode no
2.使用bind
3.設置密碼
protected-mode它啟用的條件有兩個,第一是沒有使用bind,第二是沒有設置訪問密碼。
redis數據類型及api操作(http://redisdoc.com/)
key
keys *
scan 0 match * count 1
exists key 判斷某個key是否存在
move key db 當前庫就沒有了,到指定的庫中去了
expire key 為給定的key設置過期時間
ttl key 查看還有多少時間過期 -1表示永不過期 -2表示已過期
type key 查看key是什么類型
1.string
string是redis最基本的類型,你可以理解成與Memcached一模一樣的類型,一個key對應一個value。
string類型是二進制安全的。意思是redis的string可以包含任何數據。比如jpg圖片或者序列化的對象 。
string類型是Redis最基本的數據類型,一個redis中字符串value最多可以是512M
set key value 設置key value
get key 查看當前key的值
del key 刪除key
append key value 如果key存在,則在指定的key末尾添加,如果key存在則類似set
strlen key 返回此key的長度
以下幾個命令只有在key值為數字的時候才能正常操作
incr key 為執定key的值加一
decr key 為指定key的值減一
incrby key 數值 為指定key的值增加數值
decrby key 數值 為指定key的值減數值
getrange key 0(開始位置) -1(結束位置) 獲取指定區間范圍內的值,類似between......and的關系 (0 -1)表示全部
setrange key 1(開始位置,從哪里開始設置) 具體值 設置(替換)指定區間范圍內的值
setex 鍵 秒值 真實值 設置帶過期時間的key,動態設置。
setnx key value 只有在 key 不存在時設置 key 的值。
mset key1 value key2 value 同時設置一個或多個 key-value 對。
mget key1 key 2 獲取所有(一個或多個)給定 key 的值。
msetnx key1 value key2 value 同時設置一個或多個 key-value 對,當且僅當所有給定 key 都不存在。
getset key value 將給定 key 的值設為 value ,并返回 key 的舊值(old value)。
2.list
它是一個字符串鏈表,left、right都可以插入添加;
如果鍵不存在,創建新的鏈表;
如果鍵已存在,新增內容;
如果值全移除,對應的鍵也就消失了。
鏈表的操作無論是頭和尾效率都極高,但假如是對中間元素進行操作,效率就很慘淡了。
Redis 列表是簡單的字符串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)。
它的底層實際是個鏈表
lpush key value1 value2 將一個或多個值加入到列表頭部
rpush key value1 value2 將一個或多個值加入到列表底部
lrange key start end 獲取列表指定范圍的元素 (0 -1)表示全部
lpop key 移出并獲取列表第一個元素
rpop key 移出并獲取列表最后一個元素
lindex key index 通過索引獲取列表中的元素
llen 獲取列表長度
lrem key 0(數量) 值,表示刪除全部給定的值。零個就是全部值 從left往right刪除指定數量個值等于指定值的元素,返回的值為實際刪除的數量
ltrim key start(從哪里開始截) end(結束位置) 截取指定索引區間的元素,格式是ltrim list的key 起始索引 結束索引
3.set
Redis的Set是string類型的無序,不能重復的集合。
sadd key value1 value 2 向集合中添加一個或多個成員
smembers key 返回集合中所有成員
sismembers key member 判斷member元素是否是集合key的成員
scard key 獲取集合里面的元素個數
srem key value 刪除集合中指定元素
srandmember key 數值 從set集合里面隨機取出指定數值個元素 如果超過最大數量就全部取出,
spop key 隨機移出并返回集合中某個元素
smove key1 key2 value(key1中某個值) 作用是將key1中執定的值移除 加入到key2集合中
sdiff key1 key2 在第一個set里面而不在后面任何一個set里面的項(差集)
sinter key1 key2 在第一個set和第二個set中都有的 (交集)
sunion key1 key2 兩個集合所有元素(并集)
4.hash
Redis hash 是一個鍵值對集合。
Redis hash是一個string類型的field和value的映射表,hash特別適合用于存儲對象。
kv模式不變,但v是一個鍵值對
類似Java里面的Map<String,Object>
hset key (key value) 向hash表中添加一個元素
hget key key 向hash表中獲取一個元素
hmset key key1 value1 key2 value2 key3 value3 向集合中添加一個或多個元素
hmget key key1 key2 key3 向集合中獲取一個或多個元素
hgetall key 獲取在hash列表中指定key的所有字段和值
hdel key key1 key2 刪除一個或多個hash字段
hlen key 獲取hash表中字段數量
hexits key key 查看hash表中,指定key(字段)是否存在
hkeys key 獲取指定hash表中所有key(字段)
hvals key 獲取指定hash表中所有value(值)
hincrdy key key1 數量(整數) 執定hash表中某個字段加 數量 ,和incr一個意思
hincrdyfloat key key1 數量(浮點數,小數) 執定hash表中某個字段加 數量 ,和incr一個意思
hsetnx key key1 value1 與hset作用一樣,區別是不存在賦值,存在了無效。
5.zset
Redis zset 和 set 一樣也是string類型元素的集合,且不允許重復的成員。
不同的是每個元素都會關聯一個double類型的分數。
redis正是通過分數來為集合中的成員進行從小到大的排序。zset的成員是唯一的,但分數(score)卻可以重復。
zadd key score 值 score 值 向集合中添加一個或多個成員
zrange key 0 -1 表示所有 返回指定集合中所有value
zrange key 0 -1 withscores 返回指定集合中所有value和score
zrangebyscore key 開始score 結束score 返回指定score間的值
zrem key score某個對應值(value),可以是多個值 刪除元素
zcard key 獲取集合中元素個數
zcount key 開始score 結束score 獲取分數區間內元素個數
zrank key vlaue 獲取value在zset中的下標位置(根據score排序)
zscore key value 按照值獲得對應的分數
redis的持久化機制
說白了,就是在指定的時間間隔內,將內存當中的數據集快照寫入磁盤,它恢復時是將快照文件直接讀到內存
什么意思呢?我們都知道,內存當中的數據,如果我們一斷電,那么數據必然會丟失,但是玩過redis的同學應該都知道,我們一關機之后再啟動的時候數據是還在的,所以它必然是在redis啟動的時候重新去加載了持久化的文件
redis提供兩種方式進行持久化,
一種是RDB持久化默認,
另外一種是AOF(append only file)持久化。
1.RDB
是什么?
原理是redis會單獨創建(fork)一個與當前線程一模一樣的子進程來進行持久化,這個子線程的所有數據(變量。環境變量,程序程序計數器等)都和原進程一模一樣,會先將數據寫入到一個臨時文件中,待持久化結束了,再用這個臨時文件替換上次持久化好的文件,整個過程中,主進程不進行任何的io操作,這就確保了極高的性能
1.這個持久化文件在哪里
2.他什么時候fork子線程,或者什么時候觸發rdb持久化機制
shutdown時,如果沒有開啟aof,會觸發
配置文件中默認的快照配置
執行命令save或者bgsave save是只管保存,其他不管,全部阻塞 bgsave: redis會在后臺異步進行快照操作,同時可以響應客戶端的請求
執行flushall命令 但是里面是空的,無意義
2.aof(--fix) ls -l --block-size=M
是什么?
原理是將Reids的操作日志以追加的方式寫入文件,讀操作是不記錄的
1.這個持久化文件在哪里
2.觸發機制(根據配置文件配置項)
no:表示等操作系統進行數據緩存同步到磁盤(快,持久化沒保證)
always:同步持久化,每次發生數據變更時,立即記錄到磁盤(慢,安全)
everysec:表示每秒同步一次(默認值,很快,但可能會丟失一秒以內的數據)
3.aof重寫機制
當AOF文件增長到一定大小的時候Redis能夠調用 bgrewriteaof對日志文件進行重寫 。當AOF文件大小的增長率大于該配置項時自動開啟重寫(這里指超過原大小的100%)。
auto-aof-rewrite-percentage 100
當AOF文件增長到一定大小的時候Redis能夠調用 bgrewriteaof對日志文件進行重寫 。當AOF文件大小大于該配置項時自動開啟重寫
auto-aof-rewrite-min-size 64mb
4.redis4.0后混合持久化機制
開啟混合持久化
4.0版本的混合持久化默認關閉的,通過aof-use-rdb-preamble配置參數控制,yes則表示開啟,no表示禁用,5.0之后默認開啟。
混合持久化是通過bgrewriteaof完成的,不同的是當開啟混合持久化時,fork出的子進程先將共享的內存副本全量的以RDB方式寫入aof文件,然后在將重寫緩沖區的增量命令以AOF方式寫入到文件,寫入完成后通知主進程更新統計信息,并將新的含有RDB格式和AOF格式的AOF文件替換舊的的AOF文件。簡單的說:新的AOF文件前半段是RDB格式的全量數據后半段是AOF格式的增量數據,
優點:混合持久化結合了RDB持久化 和 AOF 持久化的優點, 由于絕大部分都是RDB格式,加載速度快,同時結合AOF,增量的數據以AOF方式保存了,數據更少的丟失。
缺點:兼容性差,一旦開啟了混合持久化,在4.0之前版本都不識別該aof文件,同時由于前部分是RDB格式,閱讀性較差
小總結:
1.redis提供了rdb持久化方案,為什么還要aof?
優化數據丟失問題,rdb會丟失最后一次快照后的數據,aof丟失不會超過2秒的數據
2.如果aof和rdb同時存在,聽誰的?
aof
3.rdb和aof優勢劣勢
rdb 適合大規模的數據恢復,對數據完整性和一致性不高 , 在一定間隔時間做一次備份,如果redis意外down機的話,就會丟失最后一次快照后的所有操作
aof 根據配置項而定
1.官方建議 兩種持久化機制同時開啟,如果兩個同時開啟 優先使用aof持久化機制
性能建議(這里只針對單機版redis持久化做性能建議):
因為RDB文件只用作后備用途,只要15分鐘備份一次就夠了,只保留save 900 1這條規則。
如果Enalbe AOF,好處是在最惡劣情況下也只會丟失不超過兩秒數據,啟動腳本較簡單只load自己的AOF文件就可以了。
代價一是帶來了持續的IO,二是AOF rewrite的最后將rewrite過程中產生的新數據寫到新文件造成的阻塞幾乎是不可避免的。
只要硬盤許可,應該盡量減少AOF rewrite的頻率,AOF重寫的基礎大小默認值64M太小了,可以設到5G以上。
默認超過原大小100%大小時重寫可以改到適當的數值。