Not Only SQL:不仅仅是SQL,指的就是非关系型数据库,它是关系型数据库有益的补充。最终的数据还是保存在关系型数据库中。非关系型数据库主要是提升数据库的查询速度,一般做为数据的缓存来使用。
非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。
具体表现为对如下三高问题的解决:
在同一个时间点,同时有海量的用户并发访问。往往要达到每秒上万次读写请求。关系数据库应付上万次SQL查询还勉强顶得住,但是应付上万次SQL写数据请求,硬盘IO就已经无法承受了。
如天猫的双11,从凌晨0点到2点这段时间,每秒达到上千万次的访问量。
12306春运期间,过年回家买火车抢票的时间,用户不断查询有没有剩余票。
数据库中数据量特别大,数据库表中每天产生海量的数据。
类似QQ,微信,微博,每天用户产生海量的用户动态,每天产生几千万条记录。对于关系数据库来说,在一张几亿条记录的表里面进行SQL查询,效率是极其低下乃至不可忍受的。
关系型数据库进行扩展和升级是比较麻烦的一样事,对于很多需要提供24小时不间断服务的网站来说,对数据库系统进行升级和扩展是非常痛苦的事情,往往需要停机维护和数据迁移。
非关系型数据库可以通过不断的添加服务器节点来实现扩展,而不需对原有的数据库进行维护。
redis是一种高级的key-value的存储系统,其中value支持五种数据类型,指的是它值的类型,键可以认为是字符串类型。redis不是用Java写的,是C语言写的。
值的数据类型说明string类型字符串list类型列表:元素可以重复,元素是有索引号,有先后顺序的set类型集合:元素是不可重复的,元素没有索引号,没有先后顺序的hash类型值由多个键值对组成zset类型集合:元素不可重复的,每个元素有索引号,还有一个分数值,可以根据分数进行排序在Redis中以二进制保存,没有编码和解码的过程。
无论存入的是字符串、整数、浮点类型都会以字符串写入。
在Redis中字符串类型的值最多可以容纳的数据长度是512M,这是以后最常用的数据类型。
在Redis中,List类型是按照插入顺序排序的字符串链表。和数据结构中的普通链表一样,我们可以在其左部(left)和右部(right)添加新的元素。
在插入时,如果该键并不存在,Redis将为该键创建一个新的链表。
如果链表中所有的元素均被移除,那么该键也将会被从数据库中删除。
List中可以包含的最大元素数量是4G个(41亿个)
一个Redis服务器可以包括多个数据库,客户端可以只连接Redis中某个数据库,就好比一个mysql服务器中创建多个数据库,客户端连接时指定连接到哪个数据库。
Redis中有db0-db15编号的16个数据库。我们不能创建新的数据库,也不能删除数据库。数据库中也没有表的结构,客户端默认连接第0个数据库。但可以通过配置文件设定有多少个数据库。
每个方法就是redis中的命令名,方法的参数就是命令的参数。
每个Jedis对象似于JDBC中Connection对象,获取一个Jedis对象本质上就是获取一个连接对象。
连接和关闭功能new Jedis(String host, int port)创建一个连接对象参数1:主机名参数2:端口号 6379void close()关闭连接 对string操作的方法说明set(String key,String value)添加字符串类型的键和值String get(String key)通过键获取值del(String … keys)删除一个或多个键和值 对list操作的方法说明lpush(String key,String…values)从左边添加1个或多个元素List<String> lrange(String key,long start,long end)获取一个范围内所有的元素 jedis连接资源的创建与销毁是很消耗程序性能,所以jedis为我们提供了jedis的连接池技术,jedis连接池在创建时初始化一些连接对象存储到连接池中,使用jedis连接资源时不需要自己创建jedis对象,而是从连接池中获取一个资源进行redis的操作。使用完毕后,不需要销毁该jedis连接资源,而是将该资源归还给连接池,供其他请求使用。
用于创建连接池的配置信息
JedisPoolConfig配置类功能说明JedisPoolConfig()构造方法,创建一个配置对象void setMaxTotal()连接池中最大连接数void setMaxWaitMillis()设置最长等待时间,单位是毫秒 JedisPool连接池类说明JedisPool(配置对象,服务器名,端口号)构造方法,创建连接池的类参数1:上面的配置对象参数2:服务器名参数3:端口号Jedis getResource()从连接池中获取一个创建好的连接对象,返回Jedis对象 使用连接池优化jedis操作,从连接池中得到一个创建好的Jeids对象,并且使用这个Jedis对象。向Redis数据库写入一个set集合,并且取出集合。打印到控制台,并且查看数据库中信息。
jedis.properties的内容
# 连接池的最大连接数 maxTotal=10 # 最长等待时间为2秒钟 maxWaitMillis=2000 # 服务器名字 host=localhost # 端口号 port=6379使用ResourceBundle类:
package com.itheima; import java.util.ResourceBundle; public class Demo3Resource { public static void main(String[] args) { //1. 通过静态方法读取属性文件,参数是:属性文件的主文件名,没有扩展名 ResourceBundle bundle = ResourceBundle.getBundle("jedis"); //2. 获取属性值,通过键获取值 String host = bundle.getString("host"); //3.输出值 System.out.println(host); } }利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化 持久化用于防止数据的意外丢失,确保数据安全性
永久化介质保存数据,存在硬盘
直接拷贝数据从内存到磁盘上
RDB是一个紧凑压缩的二进制文件,存储效率较高
RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
RDB恢复数据的速度要比AOF快很多
应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复。
RDB方式无论是执行指令还是利用配置,无法做到实时持久化,具有较大的可能性丢失数据
bgsave指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令 达到恢复数据的目的。与RDB相比可以简单理解为由记录数据改为记录数据产生的变化
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式
always(每次):每次写入操作均同步到AOF文件中 数据零误差,性能较低,不建议使用。
everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,在系统突然宕机的情况下丢失1秒内的数据 数据准确性较高,性能较高,建议使用,也是默认配置
no(系统控制):由操作系统控制每次同步到AOF文件的周期 整体过程不可控
对数据非常敏感,建议使用默认的AOF持久化方案
AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出 现问题时,最多丢失0-1秒内的数据。
注意:由于AOF文件存储体积较大,且恢复速度较慢
数据呈现阶段有效性,建议使用RDB持久化方案
数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段 点数据恢复通常采用RDB方案
注意:利用RDB实现紧凑的数据持久化会使Redis降的很低,慎重总结:
综合比对
RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
灾难恢复选用RDB
双保险策略,同时开启RDB 和 AOF,重启后,Redis优先使用AOF 来恢复数据,降低丢失数据的量
以上内容有失偏颇处,欢迎指正!