Redis 概述
Redis 是一個(gè)開源的內(nèi)存數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)器, 用作數(shù)據(jù)庫(kù), 緩存和消息代理.
它支持的數(shù)據(jù)結(jié)構(gòu)類型有
- 字符串string,
- 哈希 heshes,
- 列表 lists, 集合 sets,
- 帶有范圍查詢的順序集合 sorted set,
- 位圖 bitmap,
- 超級(jí)日志hyperloglogs,
- 帶有半徑查詢的地理空間索引 geospatial indexes
Redis 內(nèi)置了復(fù)制, Lua腳本, LRU 回收, 事務(wù)和不同級(jí)別的持久化, 通過 Redis sentinel 和 Redis cluster 自動(dòng)分區(qū) 提供了高可靠性
最高值
- 讀 110000 次/s
- 寫 81000 次/s
一般推薦 QPS 30000, 如果QPS 太高的話, 比如 60000 次/s, CPU過于繁忙, 軟中斷過多, 性能反而下降
Redis 快速上手
安裝
step1. brew install redis
$ find /usr/local/Cellar/redis/3.0.4/
./bin
./bin/redis-benchmark # redis performance benchmark tool
./bin/redis-check-aof # aof file repair tool
./bin/redis-check-dump # rdb file check tool
./bin/redis-cli # redis client
./bin/redis-sentinel
./bin/redis-server # redis server
./COPYING
./homebrew.mxcl.redis.plist
./INSTALL_RECEIPT.json
./README
或者通過源碼安裝
wget https://github.com/antirez/redis/archive/3.2.10.tar.gz
make
copy redis.conf redis-server /opt/redis
step2. ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents
卸載
$ brew uninstall redis
$ rm ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
使用
- 默認(rèn)端口是6379
- 啟動(dòng)
## 指定端口啟動(dòng)
redis-server --port 6666
## 指定配置文件啟動(dòng)
redis-server /usr/local/etc/redis.conf
## 使用 launchctl 啟動(dòng)
launchctl load ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
停止
redis-cli shutdown
launchctl unload ~/Library/LaunchAgents/homebrew.mxcl.redis.plist
配置文件
redis-server
redis.conf
- bind $IPAddress
- protected-mode
- requirepass
- daemonize yes
- port 6666 # default poort is 6379
- pidfile redis_6666.pid
redis-cli -h $host -p $port
auth $pass
config get ...
config set ...
文件格式
- rdb 數(shù)據(jù)文件
- aof 更新日志
命令行工具
redis-cli -h 127.0.0.1 -p 6379
redis-cli ping
redis-cli
部署模式
- one node
- master-slave
基本命令
賦值 set key value
取值 get key
遞增 inc key
遞增指定整數(shù) incby key increment
遞增指定浮點(diǎn)數(shù) incbyfloat key increment
遞減 decr key
-
追加值 append key value
127.0.0.1:6379> set greeting good
OK
127.0.0.1:6379> append greeting " morning"
(integer) 12
127.0.0.1:6379> get greeting
"good morning" 獲取字串長(zhǎng)度 strlen key
同時(shí)設(shè)置和獲取多值
mset key1 val1 key2 val2
mget key1 key2位操作
getit key offset
setbit key offset value
bitcount key [start] [end]
復(fù)合類型
哈希
就象一個(gè) map<string, string>
hset key field value
hget key
hmset key fieldname1, fieldvalue1
hmget key fieldname1, fieldname2
hgetall key
hkeys
hvals
hdel
列表
- 添加元素
從左首添加 lpush key values
lpush booklist posa1, posa2, posa2, gof
lrange booklist
從右首添加 rpush key values
- 彈出元素
從左首刪除 lpop key
從右首刪除 rpop key
列表個(gè)數(shù)
llen key列表子集
lrange key start stop
lrange booklist 0, 2
- 列表元素
lindex key index
lset key index value
集合
添加元素
sadd key members刪除元素
srem key members列表元素
smembers key查詢?cè)厥欠翊嬖?br> smember key member
集合間運(yùn)算
sdiff keys
sinter keys
sunion keys
有序集合
高級(jí)功能
事務(wù)
要么都執(zhí)行, 要么都不執(zhí)行
multi
commands...
exec
Watch
Sort
TTL
隊(duì)列Queue
生產(chǎn)者使用 rpush 來生產(chǎn)數(shù)據(jù)
消費(fèi)者使用 lpop 來消費(fèi)數(shù)據(jù)
- Producer lpush
- Cusumer roop
優(yōu)先級(jí)隊(duì)列
blpop
lpush
發(fā)布/訂閱 Pub/Sub
發(fā)布及訂閱一個(gè)頻道, 只是消息的一個(gè)分派, 如果無(wú)人訂閱這個(gè)頻道, 這條數(shù)據(jù)也不會(huì)保存
publish channel message
subscribe channels
unsubscribe channels
Redis 事務(wù)
事務(wù)開始 multi
后續(xù)操作都會(huì)入隊(duì)
執(zhí)行事務(wù) exec
取消/回滾事務(wù) discard
持久化
RDB 方式
根據(jù)時(shí)間和改動(dòng)的次數(shù)存儲(chǔ)內(nèi)存中的快照到磁盤中去
AOF 方式
AOF - Append Only File
appendonly yes
復(fù)制
主從方式 master-slave, 通過 TCP 連接將數(shù)據(jù)從master同步到slave
- master 可讀可寫, 自動(dòng)將數(shù)據(jù)變化同步給slave
- slave 只讀, 接收master 同步過來的數(shù)據(jù)
![Uploading image_933626.png . . .]
配置方式
vi redis.conf
slaveof master_ip_port
安全
requirepass xxx
通信協(xié)議
統(tǒng)一請(qǐng)求協(xié)議 unified request protocol
簡(jiǎn)單協(xié)議
Redis Cluster
工具
- phpRedisAdmin
類似于phpMyAdmin
客戶端庫(kù)
列舉一些我懂的語(yǔ)言寫的客戶端庫(kù) C/C++, Java, PHP and Node,
Ruby 和 Go 準(zhǔn)備今年先入個(gè)門
Language | Library |
---|---|
C | hiredis |
java | Jedis |
Node | node_redis |
Python | redis-py |
PHP | phpredis |
Ruby | redis-rb |
Go | Radix |
附錄
Java Client Jedis 使用
- maven configuration
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
- 代碼片斷
Jedis jedis = null;
try {
jedis = pool.getResource();
/// ... do stuff here ... for example
jedis.set("foo", "bar");
String foobar = jedis.get("foo");
jedis.zadd("sose", 0, "car"); jedis.zadd("sose", 0, "bike");
Set<String> sose = jedis.zrange("sose", 0, -1);
} finally {
if (jedis != null) {
jedis.close();
}
}
/// ... when closing your application:
pool.destroy();
Java 代碼 BasicRedisClient
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
public class BasicRedisClient {
protected final Logger LOG = LoggerFactory.getLogger(getClass());
private final JedisPool jedisPool;
public BasicRedisClient(JedisPool jPool) {
this.jedisPool = jPool;
}
public void setValue(String key, String value, int ttl) {
Jedis jedis = jedisPool.getResource();
try {
jedis.set(key, value);
jedis.expire(key, ttl);
} catch (Exception e) {
LOG.warn("Failed to set value in redis: ", e.getStackTrace()[0]);
} finally {
jedisPool.returnResource(jedis);
}
}
public String getValue(String key) {
String rValue = null;
Jedis jedis = jedisPool.getResource();
try {
rValue = jedis.get(key);
} catch (Exception e) {
LOG.warn("Failed to get value in redis: ", e.getStackTrace()[0]);
} finally {
jedisPool.returnResource(jedis);
}
return rValue;
}
public boolean removeValue(String key) {
boolean rValue = false;
Jedis jedis = jedisPool.getResource();
try {
rValue = (jedis.del(key) > 0);
} catch (Exception e) {
LOG.warn("Failed to remove value in redis: ", e.getStackTrace()[0]);
} finally {
jedisPool.returnResource(jedis);
}
return rValue;
}
}
參考資料
書籍
- 國(guó)人寫的一本 Redis入門指南
還有兩本沒看
鏈接
- 官方站點(diǎn): http://redis.io
- Redis sentinel: https://redis.io/topics/sentinel
- https://redis.io/commands/setnx