当前位置 : 首页 » 文章分类 :  开发  »  Redis

Redis

Redis基础

Redis 教程 - 菜鸟教程
http://www.runoob.com/redis/redis-intro.html

Redis 命令参考
http://doc.redisfans.com/index.html

Redis Desktop Manager
https://redisdesktop.com/download


Jedis

Jedis模糊匹配keys

Jedis Redis 模糊匹配 取得 key 列表

往Redis中初始化几条测试数据:

china:beijing
china:shandong:heze
china:shandong:jinan

Jedis jedis = new Jedis("10.110.20.152", 6379);
Set<String> set = jedis.keys("china:shandong*");
for (String key : set) {
    System.out.println(key);
}

* 0到任意多个字符
? 1个字符


redis管道

Redis的pipeline(管道)功能在命令行中没有,但redis是支持pipeline的,而且在各个语言版的client中都有相应的实现。

Pipeline在某些场景下非常有用,比如有多个command需要被“及时的”提交,而且他们对相应结果没有互相依赖,对结果响应也无需立即获得,那么pipeline就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP连接中减少了“交互往返”的时间。

不过在编码时请注意,pipeline期间将“独占”链接,此期间将不能进行非“管道”类型的其他操作,直到pipeline关闭;如果你的pipeline的指令集很庞大,为了不干扰链接中的其他操作,你可以为pipeline操作新建Client链接,让pipeline和其他正常操作分离在2个client中。

管道(pipeline)可以一次性发送多条命令并在执行完后一次性将结果返回,pipeline通过减少客户端与redis的通信次数来实现降低往返延时时间,而且Pipeline 实现的原理是队列,而队列的原理是时先进先出,这样就保证数据的顺序性。 Pipeline 的默认的同步的个数为53个,也就是说arges中累加到53条数据时会把数据提交。

需要注意到是用 pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。具体多少合适需要根据具体情况测试。

适用场景
有些系统可能对可靠性要求很高,每次操作都需要立马知道这次操作是否成功,是否数据已经写进redis了,那这种场景就不适合。

还有的系统,可能是批量的将数据写入redis,允许一定比例的写入失败,那么这种场景就可以使用了,比如10000条一下进入redis,可能失败了2条无所谓,后期有补偿机制就行了

分布式缓存Redis之Pipeline(管道)
https://blog.csdn.net/u011489043/article/details/78769428

redis集群不支持管道

redis集群客户端JedisCluster优化 - 管道(pipeline)模式支持
https://blog.csdn.net/youaremoon/article/details/51751991

redis-cluster集群模式下使用pipeline,mget,mset批量操作
https://my.oschina.net/u/1266221/blog/894308

redis-cluster官方集群模式下使用pipeline批量操作
https://blog.csdn.net/kevin_pso/article/details/53945053


直接通过Jedis使用管道

不集成spring,直接利用jedis客户端直接操作

public void test3Pipelined() {
    Jedis jedis = new Jedis("localhost");
    Pipeline pipeline = jedis.pipelined();
    long start = System.currentTimeMillis();
    for (int i = 0; i < 100000; i++) {
        pipeline.set("p" + i, "p" + i);
    }
    List<Object> results = pipeline.syncAndReturnAll();
    long end = System.currentTimeMillis();
    System.out.println("Pipelined SET: " + ((end - start)/1000.0) + " seconds");
    jedis.disconnect();
}

Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式…)介绍
http://www.blogways.net/blog/2013/06/02/jedis-demo.html


spring-data-redis 管道

List<Object> results = this.getRedisTemplate().executePipelined(new RedisCallback<Object>() {
    @Override
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
        RedisSerializer<String> keySerializer=new StringRedisSerializer();
        for (String key : keys) {
            connection.get(keySerializer.serialize(key));
        }
        return null;
    }
});

在doInRedis方法中实现需要的redis操作
doInRedis中的redis操作不会立刻执行
所有redis操作会在connection.closePipeline()之后一并提交到redis并执行,这是pipeline方式的优势
所有操作的执行结果为executePipelined()的返回值

redis pipeline简介
https://www.jianshu.com/p/a8e33e058518

我们的封装方式:

// 封装stringRedisTemplate的管道方法
public List<Object> executePipelined(RedisCallback<?> action){
    return stringRedisTemplate.executePipelined(action);
}

// 使用管道实现带过期时间的mset
public void multiSet(Map<String, String> map, long milliSeconds) {
    checkState(map != null, "Required not-null param 'map'");
    checkState(milliSeconds > 0, "Required param 'seconds' must > 0");

    executePipelined(redisConnection -> {
        RedisSerializer<String> serializer = new StringRedisSerializer();
        map.forEach((k, v) -> {
            redisConnection.set(serializer.serialize(k), serializer.serialize(v));
            redisConnection.pExpire(serializer.serialize(k), milliSeconds);
        });
        return null;
    });
}

常用redis命令

Key键

keys pattern 模糊查找key

KEYS pattern

查找所有符合给定模式 pattern 的 key 。
KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。

del key key1 key2 删除一个或多个key

DEL key [key …]
删除给定的一个或多个 key。
不存在的 key 会被忽略。

批量删除模糊匹配的keys

在可远程连接redis的跳板机或本地机器上执行:

redis-cli -h redis-host keys uds-af-* | xargs redis-cli -h redis-hostn del

先通过redis客户端执行了keys命令,模糊搜索出所有的key,通过xargs命令,将前面查询出来的key作为后面redis的del命令的输入。
注意要在远程连接redis的linux命令行中执行,不要登录到redis命令行执行。

expire key seconds 设置key的过期时间为seconds秒

expire key seconds 设置key的有效时间 单位为秒

pexpire key milliseconds

这个命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。

ttl key 返回key的生存时间(秒)

TTL key
以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。

返回值:
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。

persist key 将key设置为永久有效

PERSIST key
移除给定 key 的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。
设置有时效性的key为持久key


String字符串

get key

返回 key 所关联的字符串值。
如果 key 不存在那么返回特殊值 nil 。
假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。

mget key [key ...]

返回所有(一个或多个)给定 key 的值。
如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。因此,该命令永不失败。

set key value

set key value [EX seconds] [PX milliseconds] [NX|XX]
将字符串值 value 关联到 key 。
如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。

可选参数
从 Redis 2.6.12 版本开始, SET 命令的行为可以通过一系列参数来修改:

EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。
因为 SET 命令可以通过参数来实现和 SETNX 、 SETEX 和 PSETEX 三个命令的效果,所以将来的 Redis 版本可能会废弃并最终移除 SETNX 、 SETEX 和 PSETEX 这三个命令。

mset key value [key value ...]

同时设置一个或多个 key-value 对。
如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。

incr key

将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

本操作的值限制在 64 位(bit)有符号数字表示之内。

这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。

http://doc.redisfans.com/string/incr.html

Redis原子计数器incr,防止并发请求
https://blog.csdn.net/Roy_70/article/details/78260826

incr/decr key是原子的

Redis所有单个命令的执行都是原子性的,这与它的单线程机制有关;
Redis命令的原子性使得我们不用考虑并发问题,可以方便的利用原子性自增操作INCR实现简单计数器功能;

即使服务是多机器多进程的,incr/decr 也能保证每次返回的结果不会出现相同的值.

decr key

将 key 中储存的数字值减一。

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。

如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。

本操作的值限制在 64 位(bit)有符号数字表示之内。


hash哈希表

hget key field 返回哈希表key中的field字段值

HGET key field
返回哈希表 key 中给定域 field 的值。

hset key field value 设置哈希表key中的field值

将哈希表 key 中的域 field 的值设为 value 。
如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
如果域 field 已经存在于哈希表中,旧值将被覆盖。

hmget key field field2 返回哈希表key中多个字段值

HMGET key field [field …]
返回哈希表 key 中,一个或多个给定域的值。
如果给定的域不存在于哈希表,那么返回一个 nil 值。
因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。

hgetall key 返回哈希表key的所有字段和值

HGETALL key
返回哈希表 key 中,所有的域和值。
在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。


list列表

lrange key start stop 返回列表key指定区间内的元素

LRANGE key start stop

返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。

下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。

你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。

注意LRANGE命令和编程语言区间函数的区别

假如你有一个包含一百个元素的列表,对该列表执行 LRANGE list 0 10 ,结果是一个包含11个元素的列表,这表明 stop 下标也在 LRANGE 命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比如Ruby的 Range.new 、 Array#slice 和Python的 range() 函数。

超出范围的下标

超出范围的下标值不会引起错误。

如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,那么 LRANGE 返回一个空列表。

如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。


安装

MAC安装RedisDesktopManager

新版Redis Desktop Manager(RDM) 要自己编译才可以(除非你在官网上进行付费),通过brew安装的也只能安装0.8的版本,所有最新的版本需要我们自己编译。

Mac OS X下编译Redis Desktop Manager(RDM)
https://onew.me/2018/03/29/mac-compile-RDM/index.html

如果不想自己编译,这里有编译好的mac dmg版本
RedisDesktopManager-Mac
https://github.com/onewe/RedisDesktopManager-Mac

MAC homebrew安装redis

brew install redis
安装目录:
/usr/local/Cellar/redis/4.0.11

如果需要后台运行 redis 服务,使用命令 brew services start redis
如果不需要后台服务,则使用命令 redis-server /usr/local/etc/redis.conf


redis-cli

redis-cli,redis-cli 命令不加任何参数,默认用 6379 端口连接本地redis服务
redis-cli -h host -p port -a password,连接远程redis服务器
redis-cli -h host -p port command,直接得到命令的返回结果

redis命令行查看中文不乱码

Redis在使用命令行操作时,如果查看内容中包含中文,会显示16进制的字符串”\xe4\xb8\xad\xe5\x9b\xbd”

127.0.0.1:6379> set k1 '中国'
OK
127.0.0.1:6379> get k1
"\xe4\xb8\xad\xe5\x9b\xbd"

如果想要看到的中文不乱码,解决方案有两种:

一、使用echo

$ echo -e `redis-cli get k1`
中国

二、redis-cli 后面加上–raw

$ redis-cli -h redis-host --raw
127.0.0.1:6379> get k1
中国

概述

Redis是一个完全开源免费(遵守BSD协议)的高性能key-value内存数据库,可以用作数据库、缓存和消息中间件。

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 过期等等特性。

Redis配置

Redis的配置文件位于Redis安装目录下,文件名为redis.conf。
可以通过config命令查看或设置配置项。

读取配置

使用config get命令读取配置,语法:config get CONFIG_SETTING_NAME
其中CONFIG_SETTING_NAME为配置项名称,可包含通配符
例如 config get *获取所有配置项,config get *log*获取所有包含log的配置项

修改配置

可以通过修改redis.conf文件或使用config set命令修改配置,语法:config set CONFIG_SETTING_NAME NEW_CONFIG_VALUE

常用配置项

daemonize

daemonize no
Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程

pidfile

pidfile /var/run/redis.pid
当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定

port

port 6379
指定Redis监听端口,默认端口为6379,作者在自己的一篇博文中解释了为什么选用6379作为默认端口,因为6379在手机按键上MERZ对应的号码,而MERZ取自意大利歌女Alessia Merz的名字

bind

bind 127.0.0.1
绑定的主机地址

timeout

timeout 300
当 客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能

logfile

logfile stdout
指定日志文件名,默认为标准输出,如果配置Redis为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给/dev/null

databases

databases 16
设置数据库的数量,默认数据库为0,可以使用SELECT <dbid>命令在连接上指定数据库id

dir

dir ./
指定本地数据库存放目录

dbfilename

dbfilename dump.rdb
指定本地数据库文件名,默认值为dump.rdb

slaveof

slaveof <masterip> <masterport>
设置当本机为slav服务时,设置master服务的IP地址及端口,在Redis启动时,它会自动从master进行数据同步


上一篇 Apache-Maven-Archetype

下一篇 jQuery

阅读
4,115
阅读预计16分钟
创建日期 2017-07-05
修改日期 2018-11-16
类别
标签
百度推荐