Redis入门
NoSQL
NoSQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称。
NoSQL用于超大规模数据的存储。(例如谷歌或Facebook每天为他们的用户收集万亿比特的数据)。这些类型的数据存储不需要固定的模式,无需多余操作就可以横向扩展。
为什么需要NoSQL?
- High performance - 高并发读写
- High Storage - 海量数据的高效率存储和访问
- High Scalability && High Availability - 高可扩展性和高可用性
主流NoSQL产品
- mongoDB
- Redis
NoSQL数据库的四大分类
- 键值(Key-Value)存储 - 可以通过key快速查询到其value。一般来说,存储不管value的格式,照单全收。(Redis包含了其他功能)
- 列存储 - 顾名思义,是按列存储数据的。最大的特点是方便存储结构化和半结构化数据,方便做数据压缩,对针对某一列或者某几列的查询有非常大的IO优势。
- 文档数据库 - 文档存储一般用类似json的格式存储,存储的内容是文档型的。这样也就有有机会对某些字段建立索引,实现关系数据库的某些功能。
- 图像数据库 - 图形关系的最佳存储。使用传统关系数据库来解决的话性能低下,而且设计使用不方便
NoSQL的特点
- 易扩展
- 灵活的数据模型
- 大数据量,高性能
- 高可用
Redis
REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。
Redis使用场景
- 缓存
- 任务队列
- 网站访问统计
- 数据过期处理
- 应用排行榜
- 分布式集群架构中的session的分离
Redis的安装
参加官网Redis的安装
Download, extract and compile Redis with:
$ wget http://download.redis.io/releases/redis-4.0.9.tar.gz$ tar xzf redis-4.0.9.tar.gz
$ cd redis-4.0.9
$ make
在终端中可能会提示-bash: wget: command not found
,可使用:
curl -O http://download.redis.io/releases/redis-4.0.9.tar.gz
使用$ src/redis-server
运行redis
使用内置的客户端与Redis交互:
$ src/redis-cli
redis> set foo bar
OK
redis> get foo
"bar"
使用redis-cli shutdown
关闭redis
redis jar包下载,如果需要使用Redis连接池的话,还需要commons-pool2
Mac安装Redis Desktop Manager
可参考mac安装Redis可视化工具-Redis Desktop Manager
安装好后,先建立连接,参见How to start using RDM
效果如下:
Jedis入门
Jedis是Redis官方首选的Java客户端开发包
简单的存储,使用示例如下:
// 设置ip和端口
Jedis jedis = new Jedis("localhost", 6379);
// 保存数据
jedis.set("name", "imooc");
// 获取数据
String value = jedis.get("name");
System.out.println(value);
// 释放资源
jedis.close();
连接池方式连接,基本使用方式如下:
// 获取连接池的配置对象
JedisPoolConfig config = new JedisPoolConfig();
// 设置最大连接数
config.setMaxTotal(30);
// 设置最大空闲连接数
config.setMaxIdle(10);
// 获得连接池
JedisPool jedisPool = new JedisPool(config, "localhost", 6379);
// 获取核心对象
Jedis jedis = null;
try {
// 通过连接池获得连接对象
jedis = jedisPool.getResource();
// 设置数据
jedis.set("name", "张三");
// 获取数据
String value = jedis.get("name");
System.out.println(value);
} catch (Exception e) {
e.printStackTrace();
} finally {
//释放资源
if(jedis != null){
jedis.close();
}
if (jedisPool != null) {
jedisPool.close();
}
}
Redis的数据结构
Redis的数据结构有以下几种:
- 字符串(String)
- 字符串列表(List)
- 有序字符串集合(Sorted set)
- 字符串集合(set)
- 哈希(hash)
数据类型 | 数据类型存储的值 | 说明 |
---|---|---|
STRING(字符串) | 可以保存字符串、整数和浮点数 | 可以对字符串进行操作,比如增加字符或者求子串;如果是整数或者浮点数,可以实现计算,不如自增等 |
LIST(列表) | 它是一个链表,它的每一个节点都包含一个字符串 | Redis支持从链表的两端插入或者弹出节点,或者通过偏移对它进行裁剪;还可以读取一个或者多个节点,根据条件删除或者查找节点等 |
SET(集合) | 它是一个收集器,但是是无序的,在它里面每一个元素都是一个字符串,而且是独一无二,各不相同的 | 可以新增、读取、删除单个元素;检测一个元素是否在集合中;计算它和其他集合的交集、并集和差集等;随机从集合中读取元素 |
HASH(哈希散列表) | 类似于Java语言的Map,是一个键值对应的无序列表 | 可以增、删、查、改单个键值对,也可以获取所有的键值对 |
ZSET(有序集合) | 它是一个有序集合,可以包含字符串、整数、浮点数、分值(score),元素的排序是依据分值的大小来决定的 | 可以增、删、查、改元素,根据分值的范围或者成员来获取对应的元素 |
HyperLogLog(基数) | 它的作用是计算重复的值,以确定存储的数量 | 只提供基数的运算,不提供返回的功能 |
Key定义的要点:
- 不要过长、过短
- 统一的命名规范
字符串
在Redis中,存储字符串:
- 二进制安全的,存入和获取数据相同
- Value最多可以容纳的数据长度是512M
存储字符串常用命令
1.赋值
使用SET
命令来存储value
set server:name "fido"
2.取值
使用GET
命令来取值
GET server:name
使用getset
命令,先获取值,再设置值
getset server:name "imooc"
3.删除
使用DEL
删除某个key
DEL server:name
删除后,再获取get server:name
,返回为(nil)
4.数值的增减
incr
将指定key
的value
递增1
,如果这个值不存在,就先把值设为0
,incr
之后就变为1
了
SET connections 10
INCR connections => 11
INCR connections => 12
DEL connections
INCR connections => 1
decr
将指定key
的value
递减1
,如果这个值不存在,就先把值设为0
,decr
之后就变为-1
了
decr num => -1
incrby
将指定key
的value
,增加一个指定的值
incrby num 5 => 4
decrby
将指定key
的value
,减去一个指定的值
decrby num 5 => -1
APPEND key value
如果 key
已经存在并且是一个字符串, APPEND
命令将 value
追加到 key
原来的值的末尾,返回值是字符串的长度
127.0.0.1:6379> append num 4
(integer) 3
127.0.0.1:6379> get num
"-14"
哈希
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)
1.Hset
命令用于为哈希表中的字段赋值
- 基本语法为
HSET KEY_NAME FIELD VALUE
- 如果字段是哈希表中的一个新建字段,并且值设置成功,返回 1 。 如果哈希表中域字段已经存在且旧值已被新值覆盖,返回 0 。
127.0.0.1:6379> hset myhash username jack
(integer) 1
127.0.0.1:6379> hset myhash age 18
(integer) 1
2.Hmset
命令可以一次设置多个field-value
- 如果命令执行成功,返回 OK 。
127.0.0.1:6379> hmset myhash2 username rose age 21
OK
3.Hget
命令用于返回哈希表中指定字段的值
127.0.0.1:6379> hget myhash username
"jack"
4.Hmget
命令一次得到一个或多个给定字段的值
127.0.0.1:6379> hmget myhash username age
1) "jack"
2) "18"
5.Hkeys
命令用于获取哈希表中的所有域(field)
127.0.0.1:6379> hkeys myhash
1) "username"
2) "age"
列表
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
存储List的方式:
- ArrayList使用数组方式来存储数据,这种方式根据索引去查询数据比较快,但新增和删除元素的时候,涉及到位移操作,所以比较慢
- LinkedList使用双向链接方式,新增和删除元素的时候,比较快
- 双向链表中添加、删除数据
1.两端添加
Lpush
命令将一个或多个值插入到列表头部,返回值为列表的长度
127.0.0.1:6379> lpush mylist a b c
(integer) 3
127.0.0.1:6379> lpush mylist 1 2 3
(integer) 6
Rpush
命令用于将一个或多个值插入到列表的尾部(最右边)
2.查看列表
Redis Lrange
返回列表中指定区间内的元素,区间以偏移量 START
和 END
指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
127.0.0.1:6379> lrange mylist 0 5
1) "3"
2) "2"
3) "1"
4) "c"
5) "b"
6) "a"
3.两端弹出
Lpop
命令用于移除并返回列表的第一个元素,返回值为列表的第一个元素。 当列表 key 不存在时,返回 nil
127.0.0.1:6379> lpop mylist
"3"
Rpop
命令用于移除并返回列表的最后一个元素。
4.获取列表中元素的个数
Llen
命令用于返回列表的长度
127.0.0.1:6379> llen mylist
(integer) 5
5.其它
Lset
通过索引来设置元素的值。
127.0.0.1:6379> lset mylist 3 mmm
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1"
3) "c"
4) "mmm"
5) "a"
Linsert
命令用于在列表的元素前或者后插入元素,语法为LINSERT KEY_NAME BEFORE EXISTING_VALUE NEW_VALUE
Rpoplpush
命令用于移除列表的最后一个元素,并将该元素添加到另一个列表并返回。
redis 127.0.0.1:6379> RPUSH mylist "hello"
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist "foo"
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist "bar"
(integer) 3
redis 127.0.0.1:6379> RPOPLPUSH mylist myotherlist
"bar"
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "foo"
集合
Set
是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
常用命令:
1.Sadd
命令将一个或多个成员元素加入到集合中
127.0.0.1:6379> sadd myset a b c
(integer) 3
127.0.0.1:6379> sadd myset a
(integer) 0
2.Srem
命令用于移除集合中的一个或多个成员元素
127.0.0.1:6379> sadd myset 1 2 3
(integer) 3
127.0.0.1:6379> srem myset 1 2
(integer) 2
3.Smembers
命令返回集合中的所有的成员
4.Sismember
命令判断成员元素是否是集合的成员
有序集合
Sorted-set与set的区别:
Sorted-set的每一个成员都有一个分数与之关联,redis根据分数对成员进行从小到大的排序
持久化
Redis虽然是一种内存型数据库,一旦服务器进程退出,数据库的数据就会丢失,为了解决这个问题Redis提供了两种持久化的方案,将内存中的数据保存到磁盘中,避免数据的丢失。
- RDB持久化-将redis在内存中的的状态保存到硬盘中,它可以手动执行,也可以再
redis.conf
中配置,定期执行 - AOF持久化-将以日志的形式记录服务器所处理的每一个操作,在redis服务器启动之初,它会读取该文件,来重新构建数据库,来保证启动后数据库数据的完整