1. Redis是什么、特點、優勢
Redis是一個開源的使用C語言編寫、開源、支持網絡、可基於內存亦可持久化的日志型、高性能的Key-Value數據庫,並提供多種語言的API。
它通常被稱為數據結構服務器,因為值(value)可以是 字符串(String)、哈希(Map)、 列表(list)、集合(sets) 和 有序集合(sorted sets)等類型。
Redis 與其他 key - value 緩存產品有以下三個特點:
- Redis支持數據的持久化,可以將內存中的數據保持在磁盤中,重啟的時候可以再次加載進行使用。
- Redis不僅僅支持簡單的key-value類型的數據,同時還提供list,set,zset,hash等數據結構的存儲。
- Redis支持數據的備份,即master-slave模式的數據備份。
Redis優勢
- 性能極高 – Redis能讀的速度是110000次/s,寫的速度是81000次/s 。
- 豐富的數據類型 – Redis支持二進制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 數據類型操作。
- 原子 – Redis的所有操作都是原子性的,同時Redis還支持對幾個操作全並后的原子性執行。
- 豐富的特性 – Redis還支持 publish/subscribe, 通知, key 過期等等特性。
2. redis安裝(Linux)、啟動、退出、設置密碼、遠程連接
2.1 安裝redis (鏈接)
下載redis安裝包(如:redis-2.8.17.tar.gz)
tar -zxvf redis-2.8.17.tar.gz cd redis-2.8.17 make sudo make install
2.2 后台啟動服務端
nohup redis-server &
注:redis-server默認啟動端口是6379,沒有密碼
如果不使用默認配置文件,啟動時可以加上配置文件
nohup redis-server ~/soft/redis-2.8.17/redis.conf &
2.3 啟動客戶端、驗證
127.0.0.1:6379> ping PONG 127.0.0.1:6379> set var "hello world" OK 127.0.0.1:6379> get var "hello world"
2.4 退出
關閉redis-server
redis-cli shutdown
例子
$ps -ef | grep redis root 23422 19813 0 10:59 pts/5 00:00:08 redis-server *:6379 $sudo redis-cli shutdown [23422] 05 Mar 12:11:29.301 # User requested shutdown... [23422] 05 Mar 12:11:29.301 * Saving the final RDB snapshot before exiting. [23422] 05 Mar 12:11:29.314 * DB saved on disk [23422] 05 Mar 12:11:29.314 # Redis is now ready to exit, bye bye... [1]+ Done sudo redis-server (wd: ~/soft/redis-2.10.3) (wd now: ~/soft/redis-2.8.17) $ps -ef | grep redis jihite 30563 19813 0 12:11 pts/5 00:00:00 grep redis
注:如果設置上密碼后,單純的redis-cli是關不掉的,必須加上ip、port、passwd
sudo redis-cli -h host -p port -a passwd shutdown
退出客戶端
localhost:6379> QUIT
2.5 設立密碼
打開redis.conf找到requirepass,去掉默認,修改
requirepass yourpassword
驗證密碼的正確性
localhost:6379> auth jihite OK
2.6 遠程連接
需要已經安裝redis,可以使用redis-cli命令
redis-cli -h host -p port -a password
2.7 查看redis-server統計信息
INFO
3. Reis key
Redis是key-value的數據庫,Redis的鍵用於管理Redis的鍵,基本語法是
COMMAND KEY_NAME
例子:
localhost:6379> SET var redis OK localhost:6379> GET var "redis" localhost:6379> DEL var (integer) 1 localhost:6379> GET var (nil)
注:redis命令不區分大小寫,所以get var和GET var是等價的
序號 | Redis keys命令及描述 |
---|---|
1 | DEL key 該命令用於在 key 存在是刪除 key。 |
2 | DUMP key 序列化給定 key ,並返回被序列化的值。 |
3 | EXISTS key 檢查給定 key 是否存在。 |
4 | EXPIRE key seconds 為給定 key 設置過期時間。 |
5 | EXPIREAT key timestamp EXPIREAT 的作用和 EXPIRE 類似,都用於為 key 設置過期時間。 不同在於 EXPIREAT 命令接受的時間參數是 UNIX 時間戳(unix timestamp)。 |
6 | PEXPIRE key milliseconds 設置 key 的過期時間億以毫秒計。 |
7 | PEXPIREAT key milliseconds-timestamp 設置 key 過期時間的時間戳(unix timestamp) 以毫秒計 |
8 | KEYS pattern 查找所有符合給定模式( pattern)的 key 。例如keys * 返回所有的key |
9 | MOVE key db 將當前數據庫的 key 移動到給定的數據庫 db 當中。 |
10 | PERSIST key 移除 key 的過期時間,key 將持久保持。 |
11 | PTTL key 以毫秒為單位返回 key 的剩余的過期時間。 |
12 | TTL key 以秒為單位,返回給定 key 的剩余生存時間(TTL, time to live)。 |
13 | RANDOMKEY 從當前數據庫中隨機返回一個 key 。 |
14 | RENAME key newkey 修改 key 的名稱 |
15 | RENAMENX key newkey 僅當 newkey 不存在時,將 key 改名為 newkey 。 |
16 | TYPE key 返回 key 所儲存的值的類型。 |
4. Redis數據類型
Redis支持五種數據類型:string(字符串),hash(哈希),list(列表),set(集合)及zset(sorted set:有序集合)。
4.1 String(字符串)
- 是Redis最基本的數據類型,可以理解成與Memcached一模一樣的類型,一個key對應一個value
- 二進制安全的。意思是redis的string可以包含任何數據。比如jpg圖片或者序列化的對象
- 一個鍵最大能存儲512MB
例子
127.0.0.1:6379> set var "String type" OK 127.0.0.1:6379> get var "String type"
說明:利用set給變量var賦值“String type”;利用get獲得變量var的值
4.2 Hash(哈希)
- 是一個鍵值對集合
- 是一個string類型的field和value的映射表,hash特別適合用於存儲對象
hset,hget例子
127.0.0.1:6379> hget set1 name "jihite" 127.0.0.1:6379> hget set1 score "100" 127.0.0.1:6379> hset set2 name jihite2 (integer) 1 127.0.0.1:6379> hset set2 score 110 (integer) 1 127.0.0.1:6379> hget set1 name "jihite"
hset&hget一次只能往哈希結構里面插入一個鍵值對,如果插入多個可以用hmset&hmget
hmset, hmget例子
127.0.0.1:6379> HMSET var:1 name jihite school pku OK 127.0.0.1:6379> HGETALL var:1 1) "name" 2) "jihite" 3) "school" 4) "pku"
說明
var:1是鍵值,每個 hash 可以存儲 232 - 1 鍵值對(40多億)
HMSET用於建立hash對象,HGETALL用於獲取hash對象
hset v.s. hmset操作對比
127.0.0.1:6379> hset set5 name1 jihite1 name2 jihite2 name3 jihite3 (error) ERR wrong number of arguments for 'hset' command 127.0.0.1:6379> hmset set5 name1 jihite1 name2 jihite2 name3 jihite3 OK 127.0.0.1:6379> hget set5 name1 "jihite1" 127.0.0.1:6379> hmget set5 name1 1) "jihite1" 127.0.0.1:6379> hmget set5 name1 name2 1) "jihite1" 2) "jihite2" 127.0.0.1:6379> hget set5 name1 name2 (error) ERR wrong number of arguments for 'hget' command
4.3 LIST(列表)
例子
127.0.0.1:6379> lpush lvar 1 (integer) 1 127.0.0.1:6379> lpush lvar a (integer) 2 127.0.0.1:6379> lpush lvar ab (integer) 3 127.0.0.1:6379> lrange lvar 0 1 1) "ab" 2) "a" 127.0.0.1:6379> lrange lvar 0 10 1) "ab" 2) "a" 3) "1" 127.0.0.1:6379> lrange lvar 2 2 1) "1"
說明
lpush往列表的前邊插入;lrange后面的數字是范圍(閉區間)
列表最多可存儲 232 - 1 元素 (4294967295, 每個列表可存儲40多億)。
4.4 Set(集合)
Redis的Set是string類型的無序集合。
集合是通過哈希表實現的,所以添加,刪除,查找的復雜度都是O(1)
例子
127.0.0.1:6379> sadd setvar redis (integer) 1 127.0.0.1:6379> sadd setvar mongodb (integer) 1 127.0.0.1:6379> sadd setvar mongodb (integer) 0 127.0.0.1:6379> sadd setvar rabbitmq (integer) 1 127.0.0.1:6379> smembers setvar 1) "rabbitmq" 2) "redis" 3) "mongodb"
說明
set往集合中插入元素,smembers列舉出集合中的元素
成功插入返回1;錯誤插入返回0,例子中mongodb第二次插入時,因已經存在,故插入失敗。
4.5 zset(sorted sete:有序集合)
zset和set一樣也是String類型的集合,且不允許元素重復
zset和set不同的地方在於zset關聯一個double類型的分數,redis通過分數對集合中的元素排序
zset的元素是唯一的,但是分數是可以重復的
例子
127.0.0.1:6379> zadd zvar 1 redis (integer) 1 127.0.0.1:6379> zadd zvar 1 redis (integer) 0 127.0.0.1:6379> zadd zvar 2 redis (integer) 0 127.0.0.1:6379> 127.0.0.1:6379> zadd zvar 2 mongo (integer) 1 127.0.0.1:6379> zadd zvar 0 rabbitmq (integer) 1 127.0.0.1:6379> 127.0.0.1:6379> ZRANGEBYSCORE zvar 0 1000 1) "rabbitmq" 2) "mongo" 3) "redis" 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> zadd zvar -2 celery (integer) 1 127.0.0.1:6379> ZRANGEBYSCORE zvar 0 1000 1) "rabbitmq" 2) "mongo" 3) "redis" 127.0.0.1:6379> ZRANGEBYSCORE zvar -3 1000 1) "celery" 2) "rabbitmq" 3) "mongo" 4) "redis"
說明
成功插入返回1,否則返回0。插入已存在元素失敗--返回0
分數為float(可正、負、0)
5. Redis HyperLogLog
Redis HyperLogLog是用來做基數統計的算法。優點是,在輸入元素的數量或者體積非常非常大時,計算基數所需的空間總是固定的、並且是很小的。
在 Redis 里面,每個 HyperLogLog 鍵只需要花費 12 KB 內存,就可以計算接近 2^64 個不同元素的基 數。這和計算基數時,元素越多耗費內存就越多的集合形成鮮明對比。
注:因為HyperLogLog只會根據輸入元素來計算基數,而不會存儲輸入元素本身,因此不會返回輸入的各個元素。
基數是什么? 對於["abc", "abc", "2", "3"],基數是["abc", "2", "3"],個數是3.
例子
localhost:6379> pfadd jsh redis (integer) 1 localhost:6379> pfadd jsh redis (integer) 0 localhost:6379> pfadd jsh mongodb (integer) 1 localhost:6379> pfadd jsh rabbitmq (integer) 1 localhost:6379> pfcount jsh (integer) 3 localhost:6379> pfadd jsh2 redis (integer) 1 localhost:6379> pfadd jsh2 a (integer) 1 localhost:6379> pfcount jsh2 (integer) 2 localhost:6379> pfmerge jsh jsh2 OK localhost:6379> pfcount jsh (integer) 4 localhost:6379> pfcount jsh2 (integer) 2
說明:
- pfadd key ele [ele2 ...]:添加指定元素到HyperLogLog中,
- pfcount key: 返回給定HyperLogLog的基數估算值
- pfmerge destkey srckey [srckey2....]:講多個HyperLogLog合並到一個第一個HyperLogLog中
6. Redis 發布訂閱
Redis 發布訂閱(pub/sub)是一種消息通信模式:發送者(pub)發送消息,訂閱者(sub)接收消息。
Redis 客戶端可以訂閱任意數量的頻道。
原理:下圖展示了三個客戶端client1, client2, client5訂閱了頻道channel1
當有新消息通過PUBLISH發送給channel1時,這時候channel1就會把消息同時發布給訂閱者
例子
創建訂閱頻道redisChat
localhost:6379> subscribe redisChat Reading messages... (press Ctrl-C to quit) 1) "subscribe" 2) "redisChat" 3) (integer) 1
打開幾個客戶端,訂閱channel redisChat
localhost:6379> psubscribe redisChat Reading messages... (press Ctrl-C to quit) 1) "psubscribe" 2) "redisChat" 3) (integer) 1
然后給channel redisChat發送消息“Hello World”
localhost:6379> publish redisChat "Hello World" (integer) 1
客戶端會收到消息
Reading messages... (press Ctrl-C to quit) 1) "pmessage" 2) "redisChat" 3) "redisChat" 4) "Hello World"
7. Redis事務
事務是一個單獨的操作集合,事務中的命令有順序,是一個原子操作(事務中的命令要么全部執行,要么全部不執行),執行一個事務中的命令時不會被其他命令打斷。
一個事務從開始到結束經過以下三個階段:
- 開始事務
- 命令入隊
- 執行事務
例子
localhost:6379> MULTI OK localhost:6379> set name jihite QUEUED localhost:6379> get name QUEUED localhost:6379> sadd language "c++" "python" "java" QUEUED localhost:6379> smembers language QUEUED localhost:6379> exec 1) OK 2) "jihite" 3) (integer) 3 4) 1) "java" 2) "python" 3) "c++"
說明:事務以MULTI開始,以EXEC結束
8. Redis腳本
Redis 腳本使用 Lua 解釋器來執行腳本。執行腳本的常用命令為 EVAL。基本語法
EVAL script numkeys key [key ...] arg [arg ...]
例子
localhost:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second 1) "key1" 2) "key2" 3) "first" 4) "second"
9. 數據備份與恢復
數據備份
localhost:6379> save OK
改命令會在redis的安裝目錄中創建文件dump.rdb,並把數據保存在該文件中。
查看redis的安裝目錄
localhost:6379> config get dir 1) "dir" 2) "/home/jihite/soft/redis-2.8.17"
數據恢復
只需將備份文件dump.rdb拷貝到redis的安裝目錄即可。
10. 數據庫操作
Redis中,一共有16個數據庫,分別是0~15,一般情況下,進入數據庫默認編號是0,如果我們要進入指定數據庫,可以用select語句
切換到編號為3的數據庫
localhost:6379> select 3 OK localhost:6379[3]>
查看數據庫中所有的鍵值
localhost:6379[1]> set a 1 OK localhost:6379[1]> set b 2 OK localhost:6379[1]> keys * 1) "b" 2) "a"
返回當前數據庫中所有key的數目: dbsize
刪除當前數據庫中的所有key: flushdb
清空所有數據庫中的所有key: flushall
把當前數據庫中的key轉移到指定數據庫:move a aim_db,例:
localhost:6379[1]> set z sss OK localhost:6379[1]> move z 0 (integer) 1 localhost:6379[1]> select 0 OK localhost:6379> get z "sss"
11. 實際小應用
http://www.aboutyun.com/thread-12613-1-1.html
12. 關閉持久化
數據持久化是Redis不同於其他緩存的一個特性,具有明顯的有點。但如不希望持久化數據,只作為普通的緩存用,如memcache
方法:
修改配置文件,改完后重啟。
#save 900 1 #save 300 10 #save 60 10000
或執行操作命令
CONFIG SET save ""
執行命令后,無需重啟即可生效