redis入门——客户端篇

redis入门——客户端篇

@(Redis)[redis, 入门, 客户端命令, jdeis]

redis的客户端

redis-cli

redis-cli是redis自带的客户端,是功能最完善的,不过因为其是基于命令行的,不是特别直观。

使用redis-cli命令默认连接127.0.0.1(localhost)6379端口的服务。可以通过一些参数来指定主机和端口。 
- h:指定连接服务器的ip地址。 
- p:指定redis服务的端口号

PS:比如在《redis入门——安装篇》中使用redis-cli关闭6401端口号上的redis服务时,就使用了- p参数。

如果我想连接服务器主机IP为127.0.0.1上的6401端口的redis服务,可以通过如下命令访问:

[root@iZ28xuvyce3Z bin]# ./redis-cli  -h 127.0.0.1 -p 6401
127.0.0.1:6401> 
  • 1
  • 2

redis-desktop-manager

redis-desktop-manager是一个第三方跨平台redis的客户端,提供了图形化界面的方式操作redis数据库。

可以从官网下载该软件,现在mac os和Ubuntu版的直装版需要订阅才能获取,不过可以通过获取源代码的方式,本地编译,具体官网有教程。windows和其他Linux,像是cent os目前还是免费提供直装版的。

使用rdm连接redis服务器时需要注意防火墙是否开启端口,如果只是测试环境,可以把防火墙关闭。具体操作如下

  • 防火墙开启对应端口
[root@iZ28xuvyce3Z bin]# vim /etc/sysconfig/iptables
  • 1
-A INPUT -p tcp -m state --state NEW -m tcp --dport 6401 -j ACCEPT
  • 1
[root@iZ28xuvyce3Z bin]# service iptables restart
  • 1
  • 关闭防火墙
[root@iZ28xuvyce3Z bin]# service iptables stop
Redirecting to /bin/systemctl stop  iptables.service
[root@iZ28xuvyce3Z bin]# chkconfig iptables off
  • 1
  • 2
  • 3

jedis

下载地址:GitHub:jedis

在java程序中可以使用Jedis和JedisPool操作redis。

关于Jedis的使用,在接下来的博文中会有简单的入门案例。

redis客户端的使用(以redis-cli为例)

redis的数据类型

redis是key-value形式的nosql数据库,其数据类型如下: 
这里写图片描述

redis的各个数据类型的常用命令

常用命令

这里写图片描述

String

基本介绍

redis中没有使用C语言的字符串表示,而是自定义了一个叫SDS(simple dynamic string)即简单动态字符串,使用这个数据结构来实现字符串类型。 
- SDS的数据结构

struct sdshdr {
    //字符串长度
    unsigned int len;
    //buf数组中未使用的字节数量
    unsigned int free;
    //用于保存字符串
    char buf[];
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

在Redis中,key和value中的string类型都是使用sds来实现的。

c语言对字符串的存储是使用字符数组,遇到’\0’字符则认为字符串结束,redis的字符串可以存储任何类型的数据,因为任何类型数据都可以表示成二进制,sds结构中的char buf[]就是存储了二进制数据。

redis的字符串是二进制安全的,什么是二进制安全?简单理解就是存入什么数据取出的还是什么数据。redis中的sds不像c语言处理字符串那样遇到’\0’字符则认证字符串结束,它不会对存储进去的二进制数据进行处理,存入什么数据取出还是什么数据。

命令实例

字符整数命令
  • 添加 
    • SET key value [EX seconds] [PX milliseconds] [NX|XX]
127.0.0.1:6401> set name Switch
OK
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 获取 
    • GET key
127.0.0.1:6401> get name
"Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 自增整数一 
    • INCR key 
      • 当存储的字符串是整数时,可以使用该命令自增。
      • 作为计数器使用、生成主键。
127.0.0.1:6401> set time 10
OK
127.0.0.1:6401> get time
"10"
127.0.0.1:6401> incr time
(integer) 11
127.0.0.1:6401> incr time
(integer) 12
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 自增指定整数 
    • INCRBY key increment 
      • 指定整数为负数,则为减去相应整数
127.0.0.1:6401> incrby time 5
(integer) 17
127.0.0.1:6401> incrby time -2
(integer) 15
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 自减整数一 
    • DECR key
127.0.0.1:6401> decr time
(integer) 14
127.0.0.1:6401> decr time
(integer) 13
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 自减指定整数 
    • DECRBY key decrement
127.0.0.1:6401> decrby time 6
(integer) 7
127.0.0.1:6401> decrby time 3
(integer) 4
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 同时设置获取多个值 
    • MSET key value [key value ...]
    • MGET key [key ...]
127.0.0.1:6401> mset age 20 city "北京"
OK
127.0.0.1:6401> mget age city
1) "20"
2) "\xe5\x8c\x97\xe4\xba\xac"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

PS:存入Redis中的汉字,在redis-cli中是以编码的方式获取的,其本身还是对应汉字。在java中使用jedis获取时,则是相应汉字。

  • 获取字符串长度 
    • STRLEN key
127.0.0.1:6401> get name
"Switch"
127.0.0.1:6401> strlen name
(integer) 6
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 向字符串尾部追加值 
    • APPEND key value
127.0.0.1:6401> get name
"Switch"
127.0.0.1:6401> append name " Kity"
(integer) 11
127.0.0.1:6401> get name
"Switch Kity"
127.0.0.1:6401> get n
(nil)
127.0.0.1:6401> append n 123456
(integer) 6
127.0.0.1:6401> get n
"123456"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

PS:可以看出,当附加的key不存在时,则appendset功能一样。

二进制命令
  • 设置或清除指定偏移量上的位 
    • SETBIT key offset value
127.0.0.1:6401> setbit bit 100 1
(integer) 0
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 获取指定偏移量上的位
127.0.0.1:6401> getbit bit 100
(integer) 1
127.0.0.1:6401> getbit bit 1
(integer) 0
127.0.0.1:6401> get bit
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 计算给定字符串中,被设置为1的比特位的数量
127.0.0.1:6401> get name
"Switch Kity"
127.0.0.1:6401> bitcount name
(integer) 43
127.0.0.1:6401> get bit
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\b"
127.0.0.1:6401> bitcount bit
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

还有两个二进制命令: 
一个是BITOP,具体命令为BITOP operation destkey key [key ...],其功能是:对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。 
还有一个是BITFIELD,具体命令为BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL],其功能是将一个 Redis 字符串看作是一个由二进制位组成的数组, 并对这个数组中储存的长度不同的整数进行访问。

这两个命令想了解,可以查官方文档。

List

基本介绍

列表类型(list)可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,从列表两边删除元素,或者获得列表的某一个片段。

在Redis中散列表类型实现方式有两种,一种是压缩列表(zip list),一种是双向链表(double linked list)。压缩列表适用于包含少量值,且值要么就是小整数值,要么就是长度比较短的字符串。双向链表则是压缩列表不适用时使用。这里只讨论双向链表作为底层实现。

当使用双向链表实现时,向列表两端添加元素的时间复杂度为0(1),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。

注意:Redis的双向链表实现是双向无环链表,也就是说表头的prev和表尾的next指针都为NULL

因为列表类型内部使用的双向链表,所以完全可以通过该类型实现栈、队列、双端队列等数据结构。

  • DLL的数据结构
// 链表节点
typedef struct listNode {
    // 前置节点
    struct listNode *prev;
    // 后置节点
    struct listNode *next;
    // 节点的值
    void *value;
}listNode;

// 双向链表
struct list {
    // 表头节点
    listNode *head;
    // 表尾结点
    listNode *tail;
    // 链表所包含的节点数量
    unsigned long len;
    // 一些函数
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

命令实例

  • 从左边向list中添加元素 
    • LPUSH key value [value ...]
127.0.0.1:6401> lpush names "Switch" "Kity" "TOM"
(integer) 3
127.0.0.1:6401> lrange names 0 -1
1) "TOM"
2) "Kity"
3) "Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 从右边向list添加元素 
    • RPUSH key value [value ...]
127.0.0.1:6401> rpush names2 "Switch" "Kity" "TOM"
(integer) 3
127.0.0.1:6401> lrange names2 0 -1
1) "Switch"
2) "Kity"
3) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

PS:从上面连个命令可以看出,lpush是向表头结点添加元素,rpush是向表尾结点添加元素。

  • 从list左边取一个元素 
    • LPOP key
127.0.0.1:6401> lrange names2 0 -1
1) "Switch"
2) "Kity"
3) "TOM"
127.0.0.1:6401> lpop names2
"Switch"
127.0.0.1:6401> lrange names2 0 -1
1) "Kity"
2) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 从list右边取一个元素 
    • RPOP key
127.0.0.1:6401> lrange names2 0 -1
1) "Kity"
2) "TOM"
127.0.0.1:6401> rpop names2
"TOM"
127.0.0.1:6401> lrange names2 0 -1
1) "Kity"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 查询元素列表 
    • LRANGE key start stop
127.0.0.1:6401> lrange names 0 1
1) "TOM"
2) "Kity"
127.0.0.1:6401> lrange names 0 2
1) "TOM"
2) "Kity"
3) "Switch"
127.0.0.1:6401> lrange names 0 -1
1) "TOM"
2) "Kity"
3) "Switch"
127.0.0.1:6401>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

PS:LRANGE命令是列表类型最常用的命令之一,获取列表中的某一片段,将返回start、stop之间的所有元素(包含两端的元素),索引从0开始。索引可以是负数,如:“-1”代表最后边的一个元素。

  • 查看列表的长度 
    • LLEN key
127.0.0.1:6401> lrange names 0 -1
1) "TOM"
2) "Kity"
3) "Switch"
127.0.0.1:6401> llen names
(integer) 3
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 删除列表中指定的值 
    • LREM key count value
127.0.0.1:6401> lrange names 0 -1
1) "TOM"
2) "Kity"
3) "Switch"
4) "TOM"
5) "TOM"
6) "TOM"
127.0.0.1:6401> lrem names 2 "TOM"
(integer) 2
127.0.0.1:6401> lrange names 0 -1
1) "Kity"
2) "Switch"
3) "TOM"
4) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

LREM命令会删除列表中前count个值为value的元素,返回实际删除的元素个数。根据count值的不同,该命令的执行方式会有所不同: 
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。 
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。 
- count = 0 : 移除表中所有与 value 相等的值。

  • 获得/设置指定索引的元素值 
    • LINDEX key index
    • LSET key index value
127.0.0.1:6401> lrange names 0 -1
1) "Kity"
2) "Switch"
3) "TOM"
4) "TOM"
127.0.0.1:6401> lindex names 2
"TOM"
127.0.0.1:6401> lset names 2 "JOHN"
OK
127.0.0.1:6401> lrange names 0 -1
1) "Kity"
2) "Switch"
3) "JOHN"
4) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 只保留列表指定片段,指定范围和LRANGE一致 
    • LTRIM key start stop
127.0.0.1:6401> lrange l:list 0 -1
1) "6"
2) "5"
3) "0"
4) "2"
127.0.0.1:6401> ltrim l:list 0 2
OK
127.0.0.1:6401> lrange l:list 0 -1
1) "6"
2) "5"
3) "0"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 向列表中插入元素 
    • LINSERT key BEFORE|AFTER pivot value
127.0.0.1:6401> lrange list 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6401> linsert list after 3 4
(integer) 4
127.0.0.1:6401> lrange list 0 -1
1) "3"
2) "4"
3) "2"
4) "1"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

PS:该命令首先会在列表中从左到右查找值为pivot的元素,然后根据第二个参数是BEFORE还是AFTER来决定将value插入到该元素的前面还是后面。

  • 将元素从一个列表转移到另一个列表中
  • RPOPLPUSH source destination
127.0.0.1:6401> rpoplpush list newlist 
"1"
127.0.0.1:6401> lrange newlist 0 -1
1) "1"
127.0.0.1:6401> lrange list 0 -1
1) "3"
2) "4"
3) "2" 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Hash

基本介绍

散列类型(hash)它提供了键和值的映射。

注意:这里的键是散列类型里面的键,而不是在Redis中标识这个散列的键。也就是说,一个Redis键指向的散列类型里面有多个键值对。

值只能是字符串类型,不支持散列类型、集合类型等其它类型。为什么值不支持其他类型了,这是因为Redis设计者处于简单、高效考虑,不去支持这种复杂类型的嵌套。且使用这五种值类型,已经能满足绝大部分需求了。

在Redis中散列类型实现方式有两种、一种是压缩列表(zip list),一种是字典(dictionary),压缩列表适用于当散列中所有键和值的内容要么就是小整数,要么就是短字符串的情况。使用字典则是其他情况。这里只讨论字典作为底层实现。

  • 字典的数据结构
// 哈希表节点
typedef struct dictEntry {
    // 键
    void *key;
    // 值
    union {
        void *val;
        unit64_t u64;
        int64_t s64;
    } v;
    // 指向下个哈希表节点,形成链表
    struct dictEntry *next;
} dictEntry;

// 哈希表
typedef struct dictht {
    // 哈希表数组
    dictEntry **table;
    // 哈希表大小
    unsigned long size;
    // 哈希表大小掩码,用于计算索引值
    // 总是等于size-1
    unsigned long sizemask;
    // 该哈希表已有节点数量
    unsigned long used;
} dictht;

// 字典
typedef struct dict {
    // 类型特定函数
    ...
    // 私有数据
    void *privdata;
    // 哈希表
    dictht ht[2];
    // rehash索引
    // 当rehash不在进行时,值为-1
    int trehashidx;
} dict;
  • 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

字典之所以有持有两个哈希表的原因是因为,在使用一张哈希表的时候,将键值对存入这张使用的表的时候,同时存入另一张表,这样渐进式的rehash,可以将时间复杂度平摊到每次操作上。

hash表节点之所以有一个指向下个哈希表节点的指针是因为,hash算法不可能做到完美hash,即每个存入值hash值都不相同。那么,就有可能发生冲突,这时候就需要解决键冲突问题了。Redis中的哈希表采用的是链地址法,也就是说,每个hash值相同的键,通过链表相连接。

这里写图片描述

命令实例

  • 添加元素 
    • HSET key field value
127.0.0.1:6401> hset customer:1 name "Switch"
(integer) 1
127.0.0.1:6401> hset customer:1 age "20"
(integer) 1
127.0.0.1:6401> hset customer:1 gender "male"
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 获取元素 
    • HGET key field
127.0.0.1:6401> hget customer:1 name
"Switch"
127.0.0.1:6401> hget customer:1 age
"20"
127.0.0.1:6401> hget customer:1 gender
"male"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 批量添加元素 
    • HMSET key field value [field value ...]
127.0.0.1:6401> hmset customer:2 name "Kity" age "21" gender "female"
OK
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 批量获取数据 
    • HMGET key field [field ...]
127.0.0.1:6401> hmget customer:2 name age gender
1) "Kity"
2) "21"
3) "female"
127.0.0.1:6401> hmget customer:1 name age gender
1) "Switch"
2) "20"
3) "male"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 删除指定域 
    • HDEL key field [field ...]
127.0.0.1:6401> hmset customer:3 name "TOM" age "21" gender "male"

OK
127.0.0.1:6401> hmget customer:3 name age gender
1) "TOM"
2) "21"
3) "male"
127.0.0.1:6401> hdel customer:3 name
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 获取所有域和域对应的值 
    • HGETALL key
127.0.0.1:6401> hgetall customer:1
1) "name"
2) "Switch"
3) "age"
4) "20"
5) "gender"
6) "male"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 获取所有域 
    • HKEYS key
127.0.0.1:6401> hkeys customer:1
1) "name"
2) "age"
3) "gender"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 获取所有域对应的值 
    • HVALS key
127.0.0.1:6401> hvals customer:1
1) "Switch"
2) "20"
3) "male"
127.0.0.1:6401> hvals customer:2
1) "Kity"
2) "21"
3) "female"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 给值加上增量 
    • HINCRBY key field increment
127.0.0.1:6401> hget customer:1 money
"200"
127.0.0.1:6401> hincrby customer:1 money 100
(integer) 300
127.0.0.1:6401> hget customer:1 money
"300"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 判断域是否存在 
    • HEXISTS key field
127.0.0.1:6401> hkeys customer:1
1) "name"
2) "age"
3) "gender"
4) "money"
127.0.0.1:6401> hexists customer:1 name
(integer) 1
127.0.0.1:6401> hexists customer:1 n
(integer) 0
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 获取域的数量 
    • HLEN key
127.0.0.1:6401> hkeys customer:1
1) "name"
2) "age"
3) "gender"
4) "money"
127.0.0.1:6401> hkeys customer:2
1) "name"
2) "age"
3) "gender"
127.0.0.1:6401> hkeys customer:3
1) "age"
2) "gender"
127.0.0.1:6401> hlen customer:1
(integer) 4
127.0.0.1:6401> hlen customer:2
(integer) 3
127.0.0.1:6401> hlen customer:3
(integer) 2
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

Set

基本介绍

在集合(Set)类型中元素是无序和不同的。由此可以推测出,我们需要存储一些不需要顺序,且各个唯一的数据时,集合就是种不错的类型。

集合类型的底层实现有两种,一种是整数集合(int set),一种是字典。当集合所有对象都是整数值且元素个数不超过512个时,会使用整数集合。其他情况都是使用字典,这里也只讨论字典情况。

字典的数据类型在散列类型的介绍中已经给出,这里不再赘述。

集合类型使用字典的方式和散列使用的方式略有不同,集合只使用字典的键,而字典的值全部是被设置为NULL。也就是说集合只使用dictEntry中的key。

命令实例

基本命令
  • 向集合中添加元素 
    • SADD key member [member ...]
127.0.0.1:6401> sadd sname "Switch" "Kity" "TOM"
(integer) 3
127.0.0.1:6401> smembers sname
1) "Kity"
2) "TOM"
3) "Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 从集合中删除元素 
    • SREM key member [member ...]
127.0.0.1:6401> srem sname "TOM"
(integer) 1
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 返回集合中的所有元素 
    • SMEMBERS key
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 判断元素是否在集合中 
    • SISMEMBER key member
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> sismember sname "SWITCH"
(integer) 0
127.0.0.1:6401> sismember sname "TOM"
(integer) 0
127.0.0.1:6401> sismember sname "Switch"
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 获取集合中元素的数量 
    • SCARD key
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> scard sname
(integer) 2
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
集合命令
  • 集合的交集 
    • SINTER key [key …]
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> smembers sname2
1) "JACK"
2) "Switch"
3) "JOHN"
4) "TOM"
127.0.0.1:6401> sinter sname sname2
1) "Switch"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 集合的并集 
    • SUNION key [key ...]
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> smembers sname2
1) "JACK"
2) "Switch"
3) "JOHN"
4) "TOM"
127.0.0.1:6401> sunion sname sname2
1) "JACK"
2) "Kity"
3) "JOHN"
4) "Switch"
5) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 集合的差集 
    • SDIFF key [key ...]
127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> smembers sname2
1) "JACK"
2) "Switch"
3) "JOHN"
4) "TOM"
127.0.0.1:6401> sdiff sname sname2
1) "Kity"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

集合还有三个命令,分别是SINTERSTORESUNIONSTORESDIFFSTORE。其作用都是做了集合运算之后,将结果存入一个指定集合。

三个命令分别是: 
SINTERSTORE destination key [key ...] 
SUNIONSTORE destination key [key ...] 
SDIFFSTORE destination key [key ...]

这里只给出一个命令的实例,其余两个都差不多。

127.0.0.1:6401> smembers sname
1) "Kity"
2) "Switch"
127.0.0.1:6401> smembers sname2
1) "JACK"
2) "Switch"
3) "JOHN"
4) "TOM"
127.0.0.1:6401> sunionstore sname3 sname sname2
(integer) 5
127.0.0.1:6401> smembers sname3
1) "JACK"
2) "Kity"
3) "JOHN"
4) "Switch"
5) "TOM"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

SortedSet

基本介绍

有序集合(SortedSet)类型是在集合的基础上,为集合中的每个元素关联了一个分数(Score),通过这样的机制,不仅可以完成对集合元素的插入、删除、判重。还可以通过分数获取有序集合中最高或者最低的前N个元素、获取指定分数范围内的元素等。

有序集合类型的底层实现有两种,一种是压缩列表,一种是跳跃表(skip list)。因为两者的复杂性,这里都不介绍。如果想要了解,可以参考该博文底部的参考文档书籍。

命令实例

  • 向有序集合中添加元素 
    • ZADD key score member [[score member] [score member] ...]
127.0.0.1:6401> zadd zname 100 "Switch" 200 "Kity"
(integer) 2
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 从有序集合中删除元素 
    • ZREM key member [member ...]
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
127.0.0.1:6401> zrem zname "Switch"
(integer) 1
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Kity"
2) "200"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 查看有序集合中的元素(顺序) 
    • ZRANGE key start stop [WITHSCORES]
127.0.0.1:6401> zadd zname 100 "Switch" 300 "Tom" 400 "Card"
(integer) 3
127.0.0.1:6401> zrange zname 0 -1
1) "Switch"
2) "Kity"
3) "Tom"
4) "Card"
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zrange zname 0 2
1) "Switch"
2) "Kity"
3) "Tom"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 查看有序集合中的元素(逆序) 
    • ZREVRANGE key start stop [WITHSCORES]
127.0.0.1:6401> zrevrange zname 0 -1
1) "Card"
2) "Tom"
3) "Kity"
4) "Switch"
127.0.0.1:6401> zrevrange zname 0 -1 withscores
1) "Card"
2) "400"
3) "Tom"
4) "300"
5) "Kity"
6) "200"
7) "Switch"
8) "100"
127.0.0.1:6401> zrevrange zname 0 1 
1) "Card"
2) "Tom"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 获取指定分数范围内的成员数量 
    • ZCOUNT key min max
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zcount zname 150 350
(integer) 2
127.0.0.1:6401> zcount zname 57 165
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 获取元素的排名(正序) 
    • ZRANK key member
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zrank zname "Switch"
(integer) 0
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 获取元素的排名(逆序) 
    • ZREVRANK key member
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zrevrank zname "Switch"
(integer) 3
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 获取元素的分数 
    • ZSCORE key member
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zscore zname "Switch"
"100"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 增加元素的分数 
    • ZINCRBY key increment member
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "400"
127.0.0.1:6401> zincrby zname 66 "Card"
"466"
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "466"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 获取成员数量 
    • ZCARD key
127.0.0.1:6401> zrange zname 0 -1 withscores
1) "Switch"
2) "100"
3) "Kity"
4) "200"
5) "Tom"
6) "300"
7) "Card"
8) "466"
127.0.0.1:6401> zcard zname
(integer) 4
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Key

基本介绍

键(key)是字符串类型,它的概念很好理解,就是Redis数据库中上述五种对象的索引。在Redis中,其数据库整体的底层就是在散列类型里面介绍的字典。由此,可以得出一个结论,键的操作是通用的。也就是说,任何键的操作,比如删除,更新,对任何的值类型都是一样的。

命令实例

  • 获取所有符合给定模式的key 
    • KEYS pattern
127.0.0.1:6401> keys *
 1) "time"
 2) "city"
 3) "bii"
 4) "bi"
 5) "names"
 6) "name"
 7) "zname"
 8) "sname2"
 9) "age"
10) "customer:3"
11) "customer:2"
12) "n"
13) "names2"
14) "sname"
15) "customer:1"
16) "sname3"
17) "bit"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

KEYS * 匹配数据库中所有 key 。 
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。 
KEYS h*llo 匹配 hllo 和 heeeeello 等。 
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。

特殊符号用 \ 隔开

  • 删除指定的key 
    • DEL key [key ...]
127.0.0.1:6401> keys *
 1) "time"
 2) "city"
 3) "bii"
 4) "bi"
 5) "names"
 6) "name"
 7) "zname"
 8) "sname2"
 9) "age"
10) "customer:3"
11) "customer:2"
12) "n"
13) "names2"
14) "sname"
15) "customer:1"
16) "sname3"
17) "bit"
127.0.0.1:6401> del time city bii bi
(integer) 4
127.0.0.1:6401> keys *
 1) "names"
 2) "name"
 3) "zname"
 4) "sname2"
 5) "age"
 6) "customer:3"
 7) "customer:2"
 8) "n"
 9) "names2"
10) "sname"
11) "customer:1"
12) "sname3"
13) "bit"
127.0.0.1:6401> 
  • 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
  • 检查给定key是否存在 
    • EXISTS key
127.0.0.1:6401> keys *
 1) "names"
 2) "name"
 3) "zname"
 4) "sname2"
 5) "age"
 6) "customer:3"
 7) "customer:2"
 8) "n"
 9) "names2"
10) "sname"
11) "customer:1"
12) "sname3"
13) "bit"
127.0.0.1:6401> exists names
(integer) 1
127.0.0.1:6401> exists aaa
(integer) 0
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 查看key所存储值的类型 
    • TYPE key
127.0.0.1:6401> keys *
 1) "names"
 2) "name"
 3) "zname"
 4) "sname2"
 5) "age"
 6) "customer:3"
 7) "customer:2"
 8) "n"
 9) "names2"
10) "sname"
11) "customer:1"
12) "sname3"
13) "bit"
127.0.0.1:6401> type names
list
127.0.0.1:6401> type age
string
127.0.0.1:6401> type customer:1
hash
127.0.0.1:6401> type sname
set
127.0.0.1:6401> type zname
zset
127.0.0.1:6401> 
  • 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
  • 设置key的有效期 
    • EXPIRE key seconds
127.0.0.1:6401> keys *
 1) "names"
 2) "name"
 3) "zname"
 4) "sname2"
 5) "age"
 6) "customer:3"
 7) "customer:2"
 8) "n"
 9) "names2"
10) "sname"
11) "customer:1"
12) "sname3"
13) "bit"
127.0.0.1:6401> expire n 100
(integer) 1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 查看key的过期时间 
    • TTL key
127.0.0.1:6401> ttl n
(integer) 22
127.0.0.1:6401> ttl names
(integer) -1
127.0.0.1:6401> ttl aaaa
(integer) -2
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

  • 将key的有效期设为永不过期 
    • PERSIST key
127.0.0.1:6401> keys *
 1) "names"
 2) "name"
 3) "zname"
 4) "sname2"
 5) "age"
 6) "customer:3"
 7) "customer:2"
 8) "names2"
 9) "sname"
10) "customer:1"
11) "sname3"
12) "bit"
127.0.0.1:6401> expire bit 100
(integer) 1
127.0.0.1:6401> ttl bit
(integer) 83
127.0.0.1:6401> persist bit
(integer) 1
127.0.0.1:6401> ttl bit
(integer) -1
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 更改key的名字 
    • RENAME key newkey
127.0.0.1:6401> keys *n*
1) "names"
2) "name"
3) "zname"
4) "sname2"
5) "names2"
6) "sname"
7) "sname3"
127.0.0.1:6401> rename sname3 sname4
OK
127.0.0.1:6401> keys *n*
1) "names"
2) "name"
3) "zname"
4) "sname2"
5) "sname4"
6) "names2"
7) "sname"
127.0.0.1:6401> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

jedis基本使用

jedis工具类

package com.pc.mystore.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Redis的工具类
 * 
 * @author Switch
 * @data 2016年11月4日
 * @version V1.0
 */
public class JedisUtils {
    private static JedisPool jedisPool = null;
    private static JedisPoolConfig poolConfig = null;
    static {
        // 静态块初始化Jedis连接池
        // 连接池配置信息
        poolConfig = new JedisPoolConfig();
        // 配置最大连接时
        poolConfig.setMaxTotal(20);
        // 配置最大空闲连接数
        poolConfig.setMaxIdle(2);

        try {
            // 获取配置文件
            InputStream inputStream = JedisUtils.class.getClassLoader().getResourceAsStream("jedis-config.properties");
            Properties props = new Properties();
            props.load(inputStream);
            // 获取主机名
            String host = props.getProperty("host");
            // 获取端口号
            Integer port = Integer.valueOf(props.getProperty("port"));
            jedisPool = new JedisPool(poolConfig, host, port);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获得Redis连接
     * 
     * @return jedis对象
     */
    public static Jedis getJedis() {
        return jedisPool.getResource();
    }

    /**
     * 释放Redis连接回连接池
     * 
     * @param jedis
     *            jedis对象
     */
    public static void release(Jedis jedis) {
        jedis.close();
    }

    public static void main(String[] args) {
        Jedis jedis = getJedis();
        jedis.set("name", "Switch");
        System.out.println(jedis.get("name"));
    }
}
  • 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

配置文件:jedis-config.properties

# jedis配置文件
host=192.168.128.130
port=6379
  • 1
  • 2
  • 3

jedis使用案例

CategoryServiceInter categoryService = new CategoryServiceImpl();

public String findCategories(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    // 获取缓存中的商品分类信息
    Jedis jedis = JedisUtils.getJedis();
    String categoryList = jedis.get("categoryList");

    // 如果缓存中没有,则去数据库中查询,再设置到Redis中,释放连接
    if (categoryList == null) {
        categoryList = categoryService.findCategoriesAjax();
        jedis.set("categoryList", categoryList);
    }
    // 释放Jedis连接
    JedisUtils.release(jedis);

    // 返回ajax格式商品分类信息
    response.getWriter().write(categoryList);

    return null;
}

猜你喜欢

转载自blog.csdn.net/maxiao1204/article/details/80489278