Redis(Windows安装方法与Java调用实例 & 配置文件参数说明 & Java使用Redis所用Jar包 & Redis与Memcached区别 & redis-cli.exe命令及示例)

Windows 下 Redis 的安装使用

0. 前言

    因为是初次使用,所以是在 windows 下进行安装和使用,参考了几篇博客,下面整理一下

1. 安装 Redis

官方网站:http://redis.io/

官方下载:http://redis.io/download 可以根据需要下载不同版本

windows 版:https://github.com/MSOpenTech/redis

github 的资源可以 ZIP 直接下载的(这个是给不知道的同学友情提示下)

下载完成后 可以右键解压到 某个硬盘下 比如 D:\Redis\redis-2.6

在 D:\Redis\redis-2.6\bin\release 下 有两个 zip 包 一个 32 位一个 64 位 

根据自己 windows 的位数 解压到 D:\Redis\redis-2.6 根目录下

2. 启动 Redis

进入 redis 目录后 开启服务  (注意加上 redis.conf)

1
redis-server.exe redis.conf

这个窗口要保持开启  关闭时 redis 服务会自动关闭

redis 会自动保存数据到硬盘 所以图中是我第二次开启时 多了一个 DB loaded from disk 

3. 测试使用

另外开启一个命令行窗口 进入 redis 目录下 (注意修改自己的 ip)

1
redis-cli.exe -h 192.168.10.61 -p 6379

4.Java 开发包 Jedis

Jedis :http://www.oschina.net/p/jedis (Redis 的官方首选 Java 开发包)

1
2
3
4
5
6
7
8
<!--Redis -->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.0.0</version>
            <type>jar</type>
            <scope>compile</scope>
        </dependency>

测试例子原帖:http://flychao88.iteye.com/blog/1527163

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.lujianing.utils;
 
import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
 
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
 * Created by therunningfish on 14-2-28.
 */
public class JedisUtilTest {
 
 
 
        JedisPool pool;
        Jedis jedis;
        @Before
        public void setUp() {
            pool = new JedisPool(new JedisPoolConfig(), "192.168.10.61");
 
            jedis = pool.getResource();
         //   jedis.auth("password");
        }
 
 
        @Test
        public void testGet(){
            System.out.println(jedis.get("lu"));
        }
 
        /**
         * Redis存储初级的字符串
         * CRUD
         */
        @Test
        public void testBasicString(){
            //-----添加数据----------
            jedis.set("name","minxr");//向key-->name中放入了value-->minxr
            System.out.println(jedis.get("name"));//执行结果:minxr
 
            //-----修改数据-----------
            //1、在原来基础上修改
            jedis.append("name","jarorwar");   //很直观,类似map 将jarorwar append到已经有的value之后
            System.out.println(jedis.get("name"));//执行结果:minxrjarorwar
 
            //2、直接覆盖原来的数据
            jedis.set("name","therunningfish");
            System.out.println(jedis.get("name"));//执行结果:therunningfish
 
            //删除key对应的记录
            jedis.del("name");
            System.out.println(jedis.get("name"));//执行结果:null
 
            /**
             * mset相当于
             * jedis.set("name","minxr");
             * jedis.set("jarorwar","therunningfish");
             */
            jedis.mset("name","minxr","jarorwar","therunningfish");
            System.out.println(jedis.mget("name","jarorwar"));
 
        }
 
        /**
         * jedis操作Map
         */
        @Test
        public void testMap(){
            Map<String,String> user=new HashMap<String,String>();
            user.put("name","minxr");
            user.put("pwd","password");
            jedis.hmset("user",user);
            //取出user中的name,执行结果:[minxr]-->注意结果是一个泛型的List
            //第一个参数是存入redis中map对象的key,后面跟的是放入map中的对象的key,后面的key可以跟多个,是可变参数
            List<String> rsmap = jedis.hmget("user", "name");
            System.out.println(rsmap);
 
            //删除map中的某个键值
//        jedis.hdel("user","pwd");
            System.out.println(jedis.hmget("user", "pwd")); //因为删除了,所以返回的是null
            System.out.println(jedis.hlen("user")); //返回key为user的键中存放的值的个数1
            System.out.println(jedis.exists("user"));//是否存在key为user的记录 返回true
            System.out.println(jedis.hkeys("user"));//返回map对象中的所有key  [pwd, name]
            System.out.println(jedis.hvals("user"));//返回map对象中的所有value  [minxr, password]
 
            Iterator<String> iter=jedis.hkeys("user").iterator();
            while (iter.hasNext()){
                String key = iter.next();
                System.out.println(key+":"+jedis.hmget("user",key));
            }
 
        }
 
        /**
         * jedis操作List
         */
        @Test
        public void testList(){
            //开始前,先移除所有的内容
            jedis.del("java framework");
            System.out.println(jedis.lrange("java framework",0,-1));
            //先向key java framework中存放三条数据
            jedis.lpush("java framework","spring");
            jedis.lpush("java framework","struts");
            jedis.lpush("java framework","hibernate");
            //再取出所有数据jedis.lrange是按范围取出,
            // 第一个是key,第二个是起始位置,第三个是结束位置,jedis.llen获取长度 -1表示取得所有
            System.out.println(jedis.lrange("java framework",0,-1));
        }
 
        /**
         * jedis操作Set
         */
        @Test
        public void testSet(){
            //添加
            jedis.sadd("sname","minxr");
            jedis.sadd("sname","jarorwar");
            jedis.sadd("sname","therunningfish");
            jedis.sadd("sanme","noname");
            //移除noname
            jedis.srem("sname","noname");
            System.out.println(jedis.smembers("sname"));//获取所有加入的value
            System.out.println(jedis.sismember("sname", "minxr"));//判断 minxr 是否是sname集合的元素
            System.out.println(jedis.srandmember("sname"));
            System.out.println(jedis.scard("sname"));//返回集合的元素个数
        }
 
        @Test
        public void test() throws InterruptedException {
            //keys中传入的可以用通配符
            System.out.println(jedis.keys("*")); //返回当前库中所有的key  [sose, sanme, name, jarorwar, foo, sname, java framework, user, braand]
            System.out.println(jedis.keys("*name"));//返回的sname   [sname, name]
            System.out.println(jedis.del("sanmdde"));//删除key为sanmdde的对象  删除成功返回1 删除失败(或者不存在)返回 0
            System.out.println(jedis.ttl("sname"));//返回给定key的有效时间,如果是-1则表示永远有效
            jedis.setex("timekey", 10, "min");//通过此方法,可以指定key的存活(有效时间) 时间为秒
            Thread.sleep(5000);//睡眠5秒后,剩余时间将为<=5
            System.out.println(jedis.ttl("timekey"));   //输出结果为5
            jedis.setex("timekey", 1, "min");        //设为1后,下面再看剩余时间就是1了
            System.out.println(jedis.ttl("timekey"));  //输出结果为1
            System.out.println(jedis.exists("key"));//检查key是否存在
            System.out.println(jedis.rename("timekey","time"));
            System.out.println(jedis.get("timekey"));//因为移除,返回为null
            System.out.println(jedis.get("time")); //因为将timekey 重命名为time 所以可以取得值 min
 
            //jedis 排序
            //注意,此处的rpush和lpush是List的操作。是一个双向链表(但从表现来看的)
            jedis.del("a");//先清除数据,再加入数据进行测试
            jedis.rpush("a", "1");
            jedis.lpush("a","6");
            jedis.lpush("a","3");
            jedis.lpush("a","9");
            System.out.println(jedis.lrange("a",0,-1));// [9, 3, 6, 1]
            System.out.println(jedis.sort("a")); //[1, 3, 6, 9]  //输入排序后结果
            System.out.println(jedis.lrange("a",0,-1));
 
        }
 
 
}

Redis 会定时 保存数据到硬盘上

 

 

=========================================================================================

 

配置文件参数说明

 

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

    daemonize no

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

    pidfile /var/run/redis.pid

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

    port 6379

4. 绑定的主机地址

    bind 127.0.0.1

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

    timeout 300

6. 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 verbose

    loglevel verbose

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

    logfile stdout

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

    databases 16

9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合

    save <seconds> <changes>

    Redis 默认配置文件中提供了三个条件:

    save 900 1

    save 300 10

    save 60 10000

    分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改以及 60 秒内有 10000 个更改。

 

10. 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大

    rdbcompression yes

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

    dbfilename dump.rdb

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

    dir ./

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

    slaveof <masterip> <masterport>

14. 当 master 服务设置了密码保护时,slav 服务连接 master 的密码

    masterauth <master-password>

15. 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password> 命令提供密码,默认关闭

    requirepass foobared

16. 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息

    maxclients 128

17. 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 Key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 Key 存放内存,Value 会存放在 swap 区

    maxmemory <bytes>

18. 指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no

    appendonly no

19. 指定更新日志文件名,默认为 appendonly.aof

     appendfilename appendonly.aof

20. 指定更新日志条件,共有 3 个可选值: 
    no:表示等操作系统进行数据缓存同步到磁盘(快) 
    always:表示每次更新操作后手动调用 fsync() 将数据写到磁盘(慢,安全) 
    everysec:表示每秒同步一次(折衷,默认值)

    appendfsync everysec

 

21. 指定是否启用虚拟内存机制,默认值为 no,简单的介绍一下,VM 机制将数据分页存放,由 Redis 将访问量较少的页即冷数据 swap 到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章我会仔细分析 Redis 的 VM 机制)

     vm-enabled no

22. 虚拟内存文件路径,默认值为 /tmp/redis.swap,不可多个 Redis 实例共享

     vm-swap-file /tmp/redis.swap

23. 将所有大于 vm-max-memory 的数据存入虚拟内存, 无论 vm-max-memory 设置多小, 所有索引数据都是内存存储的 (Redis 的索引数据 就是 keys), 也就是说, 当 vm-max-memory 设置为 0 的时候, 其实是所有 value 都存在于磁盘。默认值为 0

     vm-max-memory 0

24. Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page 大小最好设置为 32 或者 64bytes;如果存储很大大对象,则可以使用更大的 page,如果不 确定,就使用默认值

     vm-page-size 32

25. 设置 swap 文件中的 page 数量,由于页表(一种表示页面空闲或使用的 bitmap)是在放在内存中的,,在磁盘上每 8 个 pages 将消耗 1byte 的内存。

     vm-pages 134217728

26. 设置访问 swap 文件的线程数, 最好不要超过机器的核数, 如果设置为 0, 那么所有对 swap 文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为 4

     vm-max-threads 4

27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启

    glueoutputbuf yes

28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法

    hash-max-zipmap-entries 64

    hash-max-zipmap-value 512

29. 指定是否激活重置哈希,默认为开启(后面在介绍 Redis 的哈希算法时具体介绍)

    activerehashing yes

30. 指定包含其它的配置文件,可以在同一主机上多个 Redis 实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件

    include /path/to/local.conf

 

 

=========================================================================================
 

Java 使用 Redis 所用 Jar 包

 jedis-2.6.2.jar // Jedis 主包 Java 使用 Redis 要通过 Jedis
commons-pool2-2.4.2.jar // JedisPool(new JedisPoolConfig()  继承的是 Apache 的接口
junit-4.4.jar // JUnit 测试 jar 包
 
 
=========================================================================================

Redis 与 Memcached 的区别

比较 Redis 与 Memcached 的区别,大多数都会得到以下观点:
1  Redis 不仅仅支持简单的 k/v 类型的数据,同时还提供 list,set,zset,hash 等数据结构的存储。
2  Redis 支持数据的备份,即 master-slave 模式的数据备份。
3  Redis 支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用。
抛开这些,可以深入到 Redis 内部构造去观察更加本质的区别,理解 Redis 的设计。
在 Redis 中,并不是所有的数据都一直存储在内存中的。这是和 Memcached 相比一个最大的区别。Redis 只会缓存所有的 key 的信息,如果 Redis 发现内存的使用量超过了某一个阀值,将触发 swap 的操作,Redis 根据“swappability = age*log(size_in_memory)”计 算出哪些 key 对应的 value 需要 swap 到磁盘。然后再将这些 key 对应的 value 持久化到磁盘中,同时在内存中清除。这种特性使得 Redis 可以 保持超过其机器本身内存大小的数据。当然,机器本身的内存必须要能够保持所有的 key,毕竟这些数据是不会进行 swap 操作的。同时由于 Redis 将内存 中的数据 swap 到磁盘中的时候,提供服务的主线程和进行 swap 操作的子线程会共享这部分内存,所以如果更新需要 swap 的数据,Redis 将阻塞这个 操作,直到子线程完成 swap 操作后才可以进行修改。
使用 Redis 特有内存模型前后的情况对比:
VM off: 300k keys, 4096 bytes values: 1.3G used
VM on:  300k keys, 4096 bytes values: 73M used
VM off: 1 million keys, 256 bytes values: 430.12M used
VM on:  1 million keys, 256 bytes values: 160.09M used
VM on:  1 million keys, values as large as you want, still: 160.09M used
当 从 Redis 中读取数据的时候,如果读取的 key 对应的 value 不在内存中,那么 Redis 就需要从 swap 文件中加载相应数据,然后再返回给请求方。 这里就存在一个 I/O 线程池的问题。在默认的情况下,Redis 会出现阻塞,即完成所有的 swap 文件加载后才会相应。这种策略在客户端的数量较小,进行 批量操作的时候比较合适。但是如果将 Redis 应用在一个大型的网站应用程序中,这显然是无法满足大并发的情况的。所以 Redis 运行我们设置 I/O 线程 池的大小,对需要从 swap 文件中加载相应数据的读取请求进行并发操作,减少阻塞的时间。
如果希望在海量数据的环境中使用好 Redis,我相信理解 Redis 的内存设计和阻塞的情况是不可缺少的。

 

补充的知识点:

memcached 和 redis 的比较

1 网络 IO 模型

  Memcached 是多线程,非阻塞 IO 复用的网络模型,分为监听主线程和 worker 子线程,监听线程监听网络连接,接受请求后,将连接描述字 pipe 传递给 worker 线程,进行读写 IO, 网络层使用 libevent 封装的事件库,多线程模型可以发挥多核作用,但是引入了 cache coherency 和锁的问题,比如,Memcached 最常用的 stats 命令,实际 Memcached 所有操作都要对这个全局变量加锁,进行计数等工作,带来了性能损耗。

(Memcached 网络 IO 模型)

  Redis 使用单线程的 IO 复用模型,自己封装了一个简单的 AeEvent 事件处理框架,主要实现了 epoll、kqueue 和 select,对于单纯只有 IO 操作来说,单线程可以将速度优势发挥到最大,但是 Redis 也提供了一些简单的计算功能,比如排序、聚合等,对于这些操作,单线程模型实际会严重影响整体吞吐量,CPU计算过程中,整个 IO 调度都是被阻塞住的。

  2.内存管理方面

  Memcached 使用预分配的内存池的方式,使用 slab 和大小不同的 chunk 来管理内存,Item 根据大小选择合适的 chunk 存储,内存池的方式可以省去申请 / 释放内存的开销,并且能减小内存碎片产生,但这种方式也会带来一定程度上的空间浪费,并且在内存仍然有很大空间时,新的数据也可能会被剔除,原因可以参考 Timyang 的文章:http://timyang.net/data/Memcached-lru-evictions/

  Redis 使用现场申请内存的方式来存储数据,并且很少使用 free-list 等方式来优化内存分配,会在一定程度上存在内存碎片,Redis 跟据存储命令参数,会把带过期时间的数据单独存放在一起,并把它们称为临时数据,非临时数据是永远不会被剔除的,即便物理内存不够,导致 swap 也不会剔除任何非临时数据 (但会尝试剔除部分临时数据),这点上 Redis 更适合作为存储而不是 cache。

  3. 数据一致性问题

  Memcached 提供了 cas 命令,可以保证多个并发访问操作同一份数据的一致性问题。 Redis 没有提供 cas 命令,并不能保证这点,不过 Redis 提供了事务的功能,可以保证一串 命令的原子性,中间不会被任何操作打断。

  4. 存储方式及其它方面

  Memcached 基本只支持简单的 key-value 存储,不支持枚举,不支持持久化和复制等功能

  Redis 除 key/value 之外,还支持 list,set,sorted set,hash 等众多数据结构,提供了 KEYS

  进行枚举操作,但不能在线上使用,如果需要枚举线上数据,Redis 提供了工具可以直接扫描其 dump 文件,枚举出所有数据,Redis 还同时提供了持久化和复制等功能。

  5. 关于不同语言的客户端支持

  在不同语言的客户端方面,Memcached 和 Redis 都有丰富的第三方客户端可供选择,不过因为 Memcached 发展的时间更久一些,目前看在客户端支持方面,Memcached 的很多客户端更加成熟稳定,而 Redis 由于其协议本身就比 Memcached 复杂,加上作者不断增加新的功能等,对应第三方客户端跟进速度可能会赶不上,有时可能需要自己在第三方客户端基础上做些修改才能更好的使用。

  根据以上比较不难看出,当我们不希望数据被踢出,或者需要除 key/value 之外的更多数据类型时,或者需要落地功能时,使用 Redis 比使用 Memcached 更合适。

  关于 Redis 的一些周边功能

  Redis 除了作为存储之外还提供了一些其它方面的功能,比如聚合计算、pubsub、scripting 等,对于此类功能需要了解其实现原理,清楚地了解到它的局限性后,才能正确的使用,比如 pubsub 功能,这个实际是没有任何持久化支持的,消费方连接闪断或重连之间过来的消息是会全部丢失的,又比如聚合计算和 scripting 等功能受 Redis 单线程模型所限,是不可能达到很高的吞吐量的,需要谨慎使用。

  总的来说 Redis 作者是一位非常勤奋的开发者,可以经常看到作者在尝试着各种不同的新鲜想法和思路,针对这些方面的功能就要求我们需要深入了解后再使用。

  总结:

  1.Redis 使用最佳方式是全部数据 in-memory。

  2.Redis 更多场景是作为 Memcached 的替代者来使用。

  3. 当需要除 key/value 之外的更多数据类型支持时,使用 Redis 更合适。

  4. 当存储的数据不能被剔除时,使用 Redis 更合适。

 

 

=========================================================================================

 

redis-cli.exe 命令及示例

Redis提供了丰富的命令(command)对数据库和各种数据类型进行操作,这些 command 可以在Linux终端使用。在编程时,比如使用 Redis 的 Java 语言包,这些命令都有对应的方法。下面将 Redis 提供的命令做一总结。

官网命令列表:http://redis.io/commands

1、连接操作相关的命令
quit:关闭连接(connection)
auth:简单密码认证

2、对 value 操作的命令
exists(key):确认一个 key 是否存在
del(key):删除一个 key
type(key):返回值的类型
keys(pattern):返回满足给定 pattern 的所有 key
randomkey:随机返回 key 空间的一个 key
rename(oldname, newname):将 key 由 oldname 重命名为 newname,若 newname 存在则删除 newname 表示的 key
dbsize:返回当前数据库中 key 的数目
expire:设定一个 key 的活动时间(s)
ttl:获得一个 key 的活动时间
select(index):按索引查询
move(key, dbindex):将当前数据库中的 key 转移到有 dbindex 索引的数据库
flushdb:删除当前选择数据库中的所有 key
flushall:删除所有数据库中的所有 key

3、对 String 操作的命令
set(key, value):给数据库中名称为 key 的 string 赋予值 value
get(key):返回数据库中名称为 key 的 string 的 value
getset(key, value):给名称为 key 的 string 赋予上一次的 value
mget(key1, key2,…, key N):返回库中多个 string(它们的名称为 key1,key2…)的 value
setnx(key, value):如果不存在名称为 key 的 string,则向库中添加 string,名称为 key,值为 value
setex(key, time, value):向库中添加 string(名称为 key,值为 value)同时,设定过期时间 time
mset(key1, value1, key2, value2,…key N, value N):同时给多个 string 赋值,名称为 key i 的 string 赋值 value i
msetnx(key1, value1, key2, value2,…key N, value N):如果所有名称为 key i 的 string 都不存在,则向库中添加 string,名称 key i 赋值为 value i
incr(key):名称为 key 的 string 增 1 操作
incrby(key, integer):名称为 key 的 string 增加 integer
decr(key):名称为 key 的 string 减 1 操作
decrby(key, integer):名称为 key 的 string 减少 integer
append(key, value):名称为 key 的 string 的值附加 value
substr(key, start, end):返回名称为 key 的 string 的 value 的子串

4、对 List 操作的命令
rpush(key, value):在名称为 key 的 list 尾添加一个值为 value 的元素
lpush(key, value):在名称为 key 的 list 头添加一个值为 value 的 元素
llen(key):返回名称为 key 的 list 的长度
lrange(key, start, end):返回名称为 key 的 list 中 start 至 end 之间的元素(下标从 0 开始,下同)
ltrim(key, start, end):截取名称为 key 的 list,保留 start 至 end 之间的元素
lindex(key, index):返回名称为 key 的 list 中 index 位置的元素
lset(key, index, value):给名称为 key 的 list 中 index 位置的元素赋值为 value
lrem(key, count, value):删除 count 个名称为 key 的 list 中值为 value 的元素。count 为 0,删除所有值为 value 的元素,count>0 从 头至尾删除 count 个值为 value 的元素,count<0 从尾到头删除 |count| 个值为 value 的元素。 lpop(key):返回并删除名称为 key 的 list 中的首元素 rpop(key):返回并删除名称为 key 的 list 中的尾元素 blpop(key1, key2,… key N, timeout):lpop 命令的 block 版本。即当 timeout 为 0 时,若遇到名称为 key i 的 list 不存在或该 list 为空,则命令结束。如果 timeout>0,则遇到上述情况时,等待 timeout 秒,如果问题没有解决,则对 keyi+1 开始的 list 执行 pop 操作。
brpop(key1, key2,… key N, timeout):rpop 的 block 版本。参考上一命令。
rpoplpush(srckey, dstkey):返回并删除名称为 srckey 的 list 的尾元素,并将该元素添加到名称为 dstkey 的 list 的头部

5、对 Set 操作的命令
sadd(key, member):向名称为 key 的 set 中添加元素 member
srem(key, member) :删除名称为 key 的 set 中的元素 member
spop(key) :随机返回并删除名称为 key 的 set 中一个元素
smove(srckey, dstkey, member) :将 member 元素从名称为 srckey 的集合移到名称为 dstkey 的集合
scard(key) :返回名称为 key 的 set 的基数
sismember(key, member) :测试 member 是否是名称为 key 的 set 的元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, key1, key2,…key N) :求交集并将交集保存到 dstkey 的集合
sunion(key1, key2,…key N) :求并集
sunionstore(dstkey, key1, key2,…key N) :求并集并将并集保存到 dstkey 的集合
sdiff(key1, key2,…key N) :求差集
sdiffstore(dstkey, key1, key2,…key N) :求差集并将差集保存到 dstkey 的集合
smembers(key) :返回名称为 key 的 set 的所有元素
srandmember(key) :随机返回名称为 key 的 set 的一个元素

6、对 zset(sorted set)操作的命令
zadd(key, score, member):向名称为 key 的 zset 中添加元素 member,score 用于排序。如果该元素已经存在,则根据 score 更新该元素的顺序。
zrem(key, member) :删除名称为 key 的 zset 中的元素 member
zincrby(key, increment, member) :如果在名称为 key 的 zset 中已经存在元素 member,则该元素的 score 增加 increment;否则向集合中添加该元素,其 score 的值为 increment
zrank(key, member) :返回名称为 key 的 zset(元素已按 score 从小到大排序)中 member 元素的 rank(即 index,从 0 开始),若没有 member 元素,返回“nil”
zrevrank(key, member) :返回名称为 key 的 zset(元素已按 score 从大到小排序)中 member 元素的 rank(即 index,从 0 开始),若没有 member 元素,返回“nil”
zrange(key, start, end):返回名称为 key 的 zset(元素已按 score 从小到大排序)中的 index 从 start 到 end 的所有元素
zrevrange(key, start, end):返回名称为 key 的 zset(元素已按 score 从大到小排序)中的 index 从 start 到 end 的所有元素
zrangebyscore(key, min, max):返回名称为 key 的 zset 中 score >= min 且 score <= max 的所有元素 zcard(key):返回名称为 key 的 zset 的基数 zscore(key, element):返回名称为 key 的 zset 中元素 element 的 score zremrangebyrank(key, min, max):删除名称为 key 的 zset 中 rank >= min 且 rank <= max 的所有元素 zremrangebyscore(key, min, max) :删除名称为 key 的 zset 中 score >= min 且 score <= max 的所有元素
zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):对 N 个 zset 求并集和交集,并将最后的集合保存在 dstkeyN 中。对于集合中每一个元素的 score,在进行 AGGREGATE 运算前,都要乘以对于的 WEIGHT 参数。如果没有提供 WEIGHT,默认为 1。默认的 AGGREGATE 是 SUM,即结果集合中元素 的 score 是所有集合对应元素进行 SUM 运算的值,而 MIN 和 MAX 是指,结果集合中元素的 score 是所有集合对应元素中最小值和最大值。

7、对 Hash 操作的命令
hset(key, field, value):向名称为 key 的 hash 中添加元素 field<—>value
hget(key, field):返回名称为 key 的 hash 中 field 对应的 value
hmget(key, field1, …,field N):返回名称为 key 的 hash 中 field i 对应的 value
hmset(key, field1, value1,…,field N, value N):向名称为 key 的 hash 中添加元素 field i<—>value i
hincrby(key, field, integer):将名称为 key 的 hash 中 field 的 value 增加 integer
hexists(key, field):名称为 key 的 hash 中是否存在键为 field 的域
hdel(key, field):删除名称为 key 的 hash 中键为 field 的域
hlen(key):返回名称为 key 的 hash 中元素个数
hkeys(key):返回名称为 key 的 hash 中所有键
hvals(key):返回名称为 key 的 hash 中所有键对应的 value
hgetall(key):返回名称为 key 的 hash 中所有的键(field)及其对应的 value

8、持久化
save:将数据同步保存到磁盘
bgsave:将数据异步保存到磁盘
lastsave:返回上次成功将数据保存到磁盘的 Unix 时戳
shundown:将数据同步保存到磁盘,然后关闭服务

9、远程服务控制
info:提供服务器的信息和统计
monitor:实时转储收到的请求
slaveof:改变复制策略设置
config:在运行时配置 Redis 服务器

 命令示例

1. KEYS/RENAME/DEL/EXISTS/MOVE/RENAMENX:
    # 在 Shell 命令行下启动 Redis 客户端工具。
    /> redis-cli
    # 清空当前选择的数据库,以便于对后面示例的理解。
    redis 127.0.0.1:6379> flushdb
    OK
    # 添加 String 类型的模拟数据。
    redis 127.0.0.1:6379> set mykey 2
    OK
    redis 127.0.0.1:6379> set mykey2 "hello"
    OK
    # 添加 Set 类型的模拟数据。
    redis 127.0.0.1:6379> sadd mysetkey 1 2 3
    (integer) 3
    # 添加 Hash 类型的模拟数据。
    redis 127.0.0.1:6379> hset mmtest username "stephen"
    (integer) 1
    # 根据参数中的模式,获取当前数据库中符合该模式的所有 key,从输出可以看出,该命令在执行时并不区分与 Key 关联的 Value 类型。
    redis 127.0.0.1:6379> keys my*
    1) "mysetkey"
    2) "mykey"
    3) "mykey2"
    #删除了两个 Keys。
    redis 127.0.0.1:6379> del mykey mykey2
    (integer) 2
    # 查看一下刚刚删除的 Key 是否还存在,从返回结果看,mykey 确实已经删除了。
    redis 127.0.0.1:6379> exists mykey
    (integer) 0
    # 查看一下没有删除的 Key,以和上面的命令结果进行比较。
    redis 127.0.0.1:6379> exists mysetkey
    (integer) 1
    #将当前数据库中的 mysetkey 键移入到 ID 为 1 的数据库中,从结果可以看出已经移动成功。
    redis 127.0.0.1:6379> move mysetkey 1
    (integer) 1
    # 打开 ID 为 1 的数据库。
    redis 127.0.0.1:6379> select 1
    OK
    # 查看一下刚刚移动过来的 Key 是否存在,从返回结果看已经存在了。
    redis 127.0.0.1:6379[1]> exists mysetkey
    (integer) 1
    # 在重新打开 ID 为 0 的缺省数据库。
    redis 127.0.0.1:6379[1]> select 0
    OK
    # 查看一下刚刚移走的 Key 是否已经不存在,从返回结果看已经移走。
    redis 127.0.0.1:6379> exists mysetkey
    (integer) 0
    # 准备新的测试数据。    
    redis 127.0.0.1:6379> set mykey "hello"
    OK
    # 将 mykey 改名为 mykey1
    redis 127.0.0.1:6379> rename mykey mykey1
    OK
    # 由于 mykey 已经被重新命名,再次获取将返回 nil。
    redis 127.0.0.1:6379> get mykey
    (nil)
    # 通过新的键名获取。
    redis 127.0.0.1:6379> get mykey1
    "hello"
    # 由于 mykey 已经不存在了,所以返回错误信息。
    redis 127.0.0.1:6379> rename mykey mykey1
    (error) ERR no such key
    #为 renamenx 准备测试 key
    redis 127.0.0.1:6379> set oldkey "hello"
    OK
    redis 127.0.0.1:6379> set newkey "world"
    OK
    # 由于 newkey 已经存在,因此该命令未能成功执行。
    redis 127.0.0.1:6379> renamenx oldkey newkey
    (integer) 0
    # 查看 newkey 的值,发现它也没有被 renamenx 覆盖。
    redis 127.0.0.1:6379> get newkey
    "world"
        
   2. PERSIST/EXPIRE/EXPIREAT/TTL:    
    #为后面的示例准备的测试数据。
    redis 127.0.0.1:6379> set mykey "hello"
    OK
    # 将该键的超时设置为 100 秒。
    redis 127.0.0.1:6379> expire mykey 100
    (integer) 1
    # 通过 ttl 命令查看一下还剩下多少秒。
    redis 127.0.0.1:6379> ttl mykey
    (integer) 97
    # 立刻执行 persist 命令,该存在超时的键变成持久化的键,即将该 Key 的超时去掉。
    redis 127.0.0.1:6379> persist mykey
    (integer) 1
    #ttl 的返回值告诉我们,该键已经没有超时了。
    redis 127.0.0.1:6379> ttl mykey
    (integer) -1
    #为后面的 expire 命令准备数据。
    redis 127.0.0.1:6379> del mykey
    (integer) 1
    redis 127.0.0.1:6379> set mykey "hello"
    OK
    # 设置该键的超时被 100 秒。
    redis 127.0.0.1:6379> expire mykey 100
    (integer) 1
    # 用 ttl 命令看一下当前还剩下多少秒,从结果中可以看出还剩下 96 秒。
    redis 127.0.0.1:6379> ttl mykey
    (integer) 96
    # 重新更新该键的超时时间为 20 秒,从返回值可以看出该命令执行成功。
    redis 127.0.0.1:6379> expire mykey 20
    (integer) 1
    # 再用 ttl 确认一下,从结果中可以看出果然被更新了。
    redis 127.0.0.1:6379> ttl mykey
    (integer) 17
    # 立刻更新该键的值,以使其超时无效。
    redis 127.0.0.1:6379> set mykey "world"
    OK
    # 从 ttl 的结果可以看出,在上一条修改该键的命令执行后,该键的超时也无效了。
    redis 127.0.0.1:6379> ttl mykey
    (integer) -1
   3. TYPE/RANDOMKEY/SORT:
    # 由于 mm 键在数据库中不存在,因此该命令返回 none。
    redis 127.0.0.1:6379> type mm
    none
    #mykey 的值是字符串类型,因此返回 string。
    redis 127.0.0.1:6379> type mykey
    string
    # 准备一个值是 set 类型的键。
    redis 127.0.0.1:6379> sadd mysetkey 1 2
    (integer) 2
    #mysetkey 的键是 set,因此返回字符串 set。
    redis 127.0.0.1:6379> type mysetkey
    set
    # 返回数据库中的任意键。
    redis 127.0.0.1:6379> randomkey
    "oldkey"
    # 清空当前打开的数据库。
    redis 127.0.0.1:6379> flushdb
    OK
    # 由于没有数据了,因此返回 nil。
    redis 127.0.0.1:6379> randomkey
    (nil)

 

 

=========================================================================================