文章目录
一、NoSQL的概述
NOSQL指的是 Not Only SQL(不仅仅是SQL),非关系型数据库
为什么需要NoSQL:
High performance-高并发读写
Huge Storage-海量数据的高效率存储和访问
High Scalability && High Availability-高可扩展性和搞可用性
有关NoSQL的产品:
四大分类:
一、键值对存储 =>redis
优势:查找速度比较快
劣势:存储数据缺少结构化
二、列存储
优势:查找速度比较快,扩展性强
劣势:功能比较局限性
三、文档数据库 =>MongoDB
优势:数据结构要求不严格
劣势:查询性能不是特别的高
四、图形数据库 =>应用于社交网络的数据库
优势:图结构的算法
劣势:不容易分布式集群方案
看图详细介绍和对比:
NoSQL相比关系型数据库的优点:
1、去掉了关系数据库的"关系特性" 易扩展
2、有非常高的读写性能,尤其在大数据量下
3、灵活的数据模型(无需提前简历字段)
4、高可用
缺点:
没有统一的标准 层出不穷
二、Redis概述
Redis 是互联网技术领域中使用最广泛的存储中间件,它是 Remote Dictionary Service 三个单词中加粗字母的组合。
Redis 以超高的性能、完美的文档、简洁的源码著称,国内外很多大型互联网公司都在用,比如说阿里、腾讯、GitHub、Stack Overflow 等等。它的版本更新非常的快,功能也越来越强大,最初只是用来作为缓存数据库,现在已经可以用它来实现消息队列了。
高性能键值对数据库,支持的键值数据类型:
字符串类型、散列类型、列表类型、集合类型、有序集合类型
借鉴一下菜鸟教程的Redis介绍:
Redis 优势:
性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。
丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。
原子 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。
丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。
Redis与其他key-value存储有什么不同?
Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。
Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。
应用场景:
1.缓存
2.聊天室,秒杀,任务队列(list结构,pop(弹出),push(插入))
3.数据存储(add,del,update,select)定期持久化到硬盘中
4.网站统计
5.数据过期处理
6.分布式集群架构中的session分离
下面便进行Redis安装(以Windows为例)
Redis下载
有两种安装方式,第一种是 msi 的方式,双击运行后安装;第二种是免安装,绿色版,只需要把 zip 包解压就可以了。
第二种:
Windows Service Documentation.docx,教我们如何安装 Redis 服务、如何启动、如何关闭,以及如何使用自定义端口启动服务
打开命令行,进入到当前解压后的目录,输入启动命令:
redis-server redis.windows.conf
其中的信息意思是:
Redis 当前的版本号为 3.0.504
端口是 6379
进程 ID,也就是 PID 为 23764
Redis 官方地址为:http://redis.io
那如何停止服务呢?可以直接按下 Ctrl+C
Redis数据结构:
Redis 有 5 种基础数据结构,String、Hash、List、Set、SortedSet
除此之外,还有高级数据结构: HyperLogLog、Geo、Pub/Sub
下面我们便用String来进行简单的操作:
上面的Redis启动后不要关闭,找到Redis 的解压目录下有一个名叫 redis-cli.exe 的文件,这是 Redis 自带的一个客户端工具,可以用来连接之前我们启动好的 Redis 服务,双击它:
操作开始:
1、set 命令用来存储一个键值对,在本例中,name 为 key,cmower 为 值。
2、get 命令用来获取一个键值对。
3、exists 命令用来测试一个键值对是否存在,(integer) 1 表示存在,(integer) 0 表示不存在。
4、del 命令用来删除一个键值对,(integer) 1 表示执行成功,(integer) 0 表示执行失败。
5、当键值对删除后,再通过 get 命令获取时,结果就为 (nil) 。
可能有人对nil不清楚:
nil 是一种类型,它只有一个值 nil,它的主要功能是用于区别其他任何值,就像之前所说的,一个全局变量在第一次赋值前的默认值就是 nil,将 nil 赋予一个全局变量等同于删除它,Lua 将 nil 用于表示一种“无效值(non-value)”的情况,即没有任何有效值的情况。
以上便是Redis简单的使用。
三、Jedis的入门
若使用myeclipse可先下载好Java客服端开发包:
Jedis是Redis官方首选的Java客户端开发包
https://github.com/xetorthio/jedis
若和我一样用IDEA,创建maven模板则:
首先注入依赖pom.xml:
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
Redis连接后,然后进行第一种单实例的测试:
JedisDemo1.java:
/**
* Jedis的测试
*/
public class JedisDemo1 {
@Test
/**
* 单实例的测试
*/
public void demo1() {
//1、设置IP地址和端口
Jedis jedis = new Jedis("127.0.0.1",6379);
//2、保存数据
jedis.set("name", "猪头");
//3、获取数据
String value = jedis.get("name");
System.out.println(value);
//4、释放资源
jedis.close();
}
}
结果为:
现在进行第二种连接池的方式连接:
@Test
/**
* 连接池方式连接
*/
public void demo2() {
//获得连接池的匹配对象
JedisPoolConfig config = new JedisPoolConfig();
//设置最大连接数
config.setMaxTotal(30);
//设置最大空闲连接数
config.setMaxIdle(10);
//获得连接池
JedisPool jedisPool = new JedisPool(config, "127.0.0.1", 6379);
//获得核心对象:
Jedis jedis = null;
try {
//通过连接池获得连接
jedis.set("name", "小baby");
//获取数据
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的数据结构
五种数据类型:
字符串(String)
字符串列表(list)
有序字符串集合(sorted set)
哈希(hash)
字符串集合(set)
Key定义的注意点:
不要过长
不要过短
统一的命名规范
1、字符串(String)
存储String:
二进制安全的,存入和获取的数据相同
Value最多可以容纳的数据长度是512M
存储String常用命令:
赋值
删除
扩展命令
取值
数值增减
可参考菜鸟教程里的内容:
序号 命令及描述
1 、SET key value
设置指定 key 的值
2 、GET key
获取指定 key 的值。
3 、GETRANGE key start end
返回 key 中字符串值的子字符
4 、GETSET key value
将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
5 、GETBIT key offset
对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
6 、MGET key1 [key2…]
获取所有(一个或多个)给定 key 的值。
7 、SETBIT key offset value
对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
8 、SETEX key seconds value
将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。
9 、SETNX key value
只有在 key 不存在时设置 key 的值。
10 、SETRANGE key offset value
用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。
11 、STRLEN key
返回 key 所储存的字符串值的长度。
12 、MSET key value [key value …]
同时设置一个或多个 key-value 对。
13 、MSETNX key value [key value …]
同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。
14 、PSETEX key milliseconds value
这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。
15 、INCR key
将 key 中储存的数字值增一。
16 、INCRBY key increment
将 key 所储存的值加上给定的增量值(increment) 。
17 、INCRBYFLOAT key increment
将 key 所储存的值加上给定的浮点增量值(increment) 。
18 、DECR key
将 key 中储存的数字值减一。
19 、DECRBY key decrement
key 所储存的值减去给定的减量值(decrement) 。
20 、APPEND key value
如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。
部分命令的使用:
2、哈希(Hash)
存储Hash
String Key和String Value的map容器
每一个Hash可以存储4294967295个键值对
存储Hash常用命令:
赋值
删除
自学命令
取值
增加数字
可参考菜鸟教程里的内容:
序号 命令及描述
1 、HDEL key field1 [field2]
删除一个或多个哈希表字段
2 、HEXISTS key field
查看哈希表 key 中,指定的字段是否存在。
3 、HGET key field
获取存储在哈希表中指定字段的值。
4 、HGETALL key
获取在哈希表中指定 key 的所有字段和值
5 、HINCRBY key field increment
为哈希表 key 中的指定字段的整数值加上增量 increment 。
6 、HINCRBYFLOAT key field increment
为哈希表 key 中的指定字段的浮点数值加上增量 increment 。
7 、HKEYS key
获取所有哈希表中的字段
8 、 HLEN key
获取哈希表中字段的数量
==9 、 ==HMGET key field1 [field2]
获取所有给定字段的值
10 、HMSET key field1 value1 [field2 value2 ]
同时将多个 field-value (域-值)对设置到哈希表 key 中。
11 、HSET key field value
将哈希表 key 中的字段 field 的值设为 value 。
12 、HSETNX key field value
只有在字段 field 不存在时,设置哈希表字段的值。
13 、HVALS key
获取哈希表中所有值。
14 、HSCAN key cursor [MATCH pattern] [COUNT count]
迭代哈希表中的键值对。
部分命令的使用:
3、字符串列表(list)
存储list:
ArrayList使用数组方式
双向链表中增加数据
LinkedList使用双向链接方式
双向链表中删除数据
存储list常用命令:
两端添加
两端弹出
查看列表
获取列表元素个数
扩展命令
可参考菜鸟教程里的内容:
序号 命令及描述
1 、BLPOP key1 [key2 ] timeout
移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
2 、BRPOP key1 [key2 ] timeout
移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
3 、BRPOPLPUSH source destination timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
4 、LINDEX key index
通过索引获取列表中的元素
5 、LINSERT key BEFORE|AFTER pivot value
在列表的元素前或者后插入元素
6 、LLEN key
获取列表长度
7 、LPOP key
移出并获取列表的第一个元素
8 、LPUSH key value1 [value2]
将一个或多个值插入到列表头部
9 、LPUSHX key value
将一个值插入到已存在的列表头部
10 、LRANGE key start stop
获取列表指定范围内的元素
11 、LREM key count value
移除列表元素
12 、LSET key index value
通过索引设置列表元素的值
13 、LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
14 、RPOP key
移除列表的最后一个元素,返回值为移除的元素。
15 、RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回
16 、RPUSH key value1 [value2]
在列表中添加一个或多个值
17 、RPUSHX key value
为已存在的列表添加值
部分命令的使用:
rpoplpush使用场景:
4、字符串集合(set)
存储Set
和List类型不同的是,Set集合中不允许出现重复的原素
Set可包含的最大元素数量是4294967295
存储set常用命令:
添加/删除元素
获得集合中的元素
集合中的差集运算
集合中的交集运算
集合中的并集运算
扩展命令
可参考菜鸟教程里的内容:
序号 命令及描述
1 、SADD key member1 [member2]
向集合添加一个或多个成员
2 、SCARD key
获取集合的成员数
3 、SDIFF key1 [key2]
返回第一个集合与其他集合之间的差异。
4 、SDIFFSTORE destination key1 [key2]
返回给定所有集合的差集并存储在 destination 中
5 、SINTER key1 [key2]
返回给定所有集合的交集
6 、SINTERSTORE destination key1 [key2]
返回给定所有集合的交集并存储在 destination 中
7 、SISMEMBER key member
判断 member 元素是否是集合 key 的成员
8 、SMEMBERS key
返回集合中的所有成员
9 、SMOVE source destination member
将 member 元素从 source 集合移动到 destination 集合
10 、SPOP key
移除并返回集合中的一个随机元素
11 、SRANDMEMBER key [count]
返回集合中一个或多个随机数
12 、SREM key member1 [member2]
移除集合中一个或多个成员
13 、SUNION key1 [key2]
返回所有给定集合的并集
14 、SUNIONSTORE destination key1 [key2]
所有给定集合的并集存储在 destination 集合中
15 、SSCAN key cursor [MATCH pattern] [COUNT count]
迭代集合中的元素
部分命令的使用:
存储 Set 使用场景:
跟踪一些唯一性数据
用于维护数据对象之间的关联关系
5、有序字符串集合(sorted set)
存储Sorted-Set
Sorted-Set和Set的区别
Sorted-Set的成员在集合中的位置是有序的
存储Sorted-set常用命令:
添加元素
获得元素
删除元素
范围查询
扩展命令
可参考菜鸟教程里的内容:
序号 命令及描述
1 、ZADD key score1 member1 [score2 member2]
向有序集合添加一个或多个成员,或者更新已存在成员的分数
2 、ZCARD key
获取有序集合的成员数
3 、ZCOUNT key min max
计算在有序集合中指定区间分数的成员数
4 、ZINCRBY key increment member
有序集合中对指定成员的分数加上增量 increment
5 、ZINTERSTORE destination numkeys key [key …]
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
6 、ZLEXCOUNT key min max
在有序集合中计算指定字典区间内成员数量
7 、ZRANGE key start stop [WITHSCORES]
通过索引区间返回有序集合指定区间内的成员
8 、ZRANGEBYLEX key min max [LIMIT offset count]
通过字典区间返回有序集合的成员
9 、ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT]
通过分数返回有序集合指定区间内的成员
10 、ZRANK key member
返回有序集合中指定成员的索引
11 、ZREM key member [member …]
移除有序集合中的一个或多个成员
12 、ZREMRANGEBYLEX key min max
移除有序集合中给定的字典区间的所有成员
13 、ZREMRANGEBYRANK key start stop
移除有序集合中给定的排名区间的所有成员
14 、ZREMRANGEBYSCORE key min max
移除有序集合中给定的分数区间的所有成员
15 、ZREVRANGE key start stop [WITHSCORES]
返回有序集中指定区间内的成员,通过索引,分数从高到低
16 、ZREVRANGEBYSCORE key max min [WITHSCORES]
返回有序集中指定分数区间内的成员,分数从高到低排序
17 、ZREVRANK key member
返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
18 、ZSCORE key member
返回有序集中,成员的分数值
19 、ZUNIONSTORE destination numkeys key [key …]
计算给定的一个或多个有序集的并集,并存储在新的 key 中
20 、ZSCAN key cursor [MATCH pattern] [COUNT count]
迭代有序集合中的元素(包括元素成员和元素分值)
部分命令的使用:
Sorted-Set 使用场景
如大型在线游戏积分排行榜
构建索引数据
五、Redis的通用命令
Keys的通用操作:
keys * -----------------------------------------------查询所有的keys
keys my? -------------------------------------------查询以my开头的keys
del mylist1 mylist2 --------------------------------删除keys
exists mylist ----------------------------------------判断keys是否存在,存在返回1,不存在返回0
rename company newcompany --------------重命名,把company改名为newcompany
expire newcompany 1000 ---------------------设置keys的超时时间
ttl newcompany -----------------------------------查看keys的剩余超时时间
type mylist ------------------------------------------查看keys的类型
六、Redis的事务
多数据库
redis最大支持16个数据库,按0~15的索引排列,默认使用的是0数据库
select index //选取数据库select 1
move keyName index //将key移动到指定数据库 move mylist 1
Redis事务
先开启两个Redis窗口,姑且叫它R1、R2吧:
R1:
R2:
R1:
R1:(提交事务)
R2:
R1:(取消该次的事务)
注意:
根据Redis的官方文档中所说的,Redis的事务是不支持回滚的。discard是指取消该次的事务,是指清空Redis服务器中事务指令队列,而不是回滚事务,回滚的概念跟这个discard是完全不一样的。
七、Redis的持久化
1、Redis持久化的介绍
所有的数据都存在内存中,从内存当中同步到硬盘上,这个过程叫做持久化过程。
持久化操作,两种方式:RDB方式、AOF方式,可以单独使用或者结合使用。
使用方法:
RDB持久化方法:在指定的时间间隔写入硬盘
AOF方式:将以日志,记录每一个操作,服务器启动后就构建数据库。
配置可以禁用持久化功能。
也可以同时使用两种方式。
2、RDB
RDB优势:
比如每个小时备份一次数据,每天备份一次最近30天的数据,可以非常容易进行恢复数据。可以把备份文件压缩转到别的机器上。性能而言,只是分出子进程进行备份操作,相对于AOF而言,如果数据集很大,RDB启动效率会更高。
RDB缺点:
保证数据的高可用性,最大限度减少数据丢失,RDB没有AOF好。肯定存在没到定时备份时间服务器宕机了RDB通过fork分叉 子进程协助数据持久化的操作,数据链大时会照成服务器停顿一段时间。
配置:
redis.windows.conf查看其文档:
900秒有一个变量发生变化,发生一次持久化
300秒,10次
60秒,10000次
3、AOF
优势:
1、更高的数据安全性
同步策略:每秒同步,每修改同步、不同步
每秒同步:异步完成,效率高,系统出现宕机,那么这一秒中修改的数据就会丢失
每修改同步:可以看作同步持久化,么一次发生数据的变化,都会立即写到磁盘当中,效率低,但是最安全
**2、**对日志文件的写入操作,采用的是追加模式(append),因此在写入过程中,即使出现了宕机的情况,也不会破坏日志文件中已经存在的内容。如果本次写入进行到一半就出现宕机,那么这种方式也不必担心,redis在下一次启动之前,可以通过redis-check-aof这个工具,帮助我们解决数据一致性的问题
**3、**如果日志过大,redis可以自动启动重写机制,redis以append模式不断的将修改的数据写入到老的磁盘文件当中,同时redis会创建一个新的文件,用于记录此期间产生的哪些修改命令被执行。因此,在进行重写切换的时候,可以更好的去保证数据的安全性
**4、**AOF包含一个格式清晰易于理解的日志文件用于记录所有的修改操作,也可以通过这个文件完成数据的重建
劣势:
1、 对于相同数量的数据集而言,AOF的文件要比RDB的文件大一些
2、 根据同步策略的不同,AOF在效率上往往低于RDB
配置:
可以发现AOF是关闭的,默认开的是RDB.
下面这个是关于同步策略的设置:
若要使用AOF,需把上面的no改为yes,打开always注释掉everysec,然后启动redis,进行操作即可。
flushall //清空数据库
redis会自动从aof文件恢复所有执行过的操作(可以去掉aof中的flushall还原所有数据)