Redis 入门
Redis 概述
Redis 是一个开源的内存数据结构存储器, 用作数据库, 缓存和消息代理.
它支持的数据结构类型有
- 字符串string,
- 哈希 heshes,
- 列表 lists, 集合 sets,
- 带有范围查询的顺序集合 sorted set,
- 位图 bitmap,
- 超级日志hyperloglogs,
- 带有半径查询的地理空间索引 geospatial indexes
Redis 内置了复制, Lua脚本, LRU 回收, 事务和不同级别的持久化, 通过 Redis sentinel 和 Redis cluster 自动分区 提供了高可靠性
最高值
- 读 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
使用
- 默认端口是6379
- 启动
## 指定端口启动
redis-server --port 6666
## 指定配置文件启动
redis-server /usr/local/etc/redis.conf
## 使用 launchctl 启动
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 数据文件
- 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
-
递增指定整数 incby key increment
-
递增指定浮点数 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" -
获取字串长度 strlen key
-
同时设置和获取多值
mset key1 val1 key2 val2
mget key1 key2 -
位操作
getit key offset
setbit key offset value
bitcount key [start] [end]
复合类型
哈希
就象一个 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
-
列表个数
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 -
查询元素是否存在
smember key member -
集合间运算
sdiff keys
sinter keys
sunion keys
有序集合
高级功能
事务
要么都执行, 要么都不执行
multi
commands...
exec
Watch
Sort
TTL
队列Queue
生产者使用 rpush 来生产数据
消费者使用 lpop 来消费数据
- Producer lpush
- Cusumer roop
优先级队列
blpop
lpush
发布/订阅 Pub/Sub
发布及订阅一个频道, 只是消息的一个分派, 如果无人订阅这个频道, 这条数据也不会保存
publish channel message
subscribe channels
unsubscribe channels
Redis 事务
事务开始 multi
后续操作都会入队
执行事务 exec
取消/回滚事务 discard
持久化
RDB 方式
根据时间和改动的次数存储内存中的快照到磁盘中去
AOF 方式
AOF - Append Only File
appendonly yes
复制
主从方式 master-slave, 通过 TCP 连接将数据从master同步到slave
- master 可读可写, 自动将数据变化同步给slave
- slave 只读, 接收master 同步过来的数据
![Uploading image_933626.png . . .]
配置方式
vi redis.conf
slaveof master_ip_port
安全
requirepass xxx
通信协议
统一请求协议 unified request protocol
简单协议
Redis Cluster
工具
- phpRedisAdmin
类似于phpMyAdmin
客户端库
列举一些我懂的语言写的客户端库 C/C++, Java, PHP and Node,
Ruby 和 Go 准备今年先入个门
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;
}
}
参考资料
书籍
- 国人写的一本 Redis入门指南
还有两本没看
链接
- 官方站点: http://redis.io
- Redis sentinel: https://redis.io/topics/sentinel
- https://redis.io/commands/setnx