在学习redis之前,我们首先需要了解一下NoSQL(非关系数据库)。非关系型数据库通常指数据以对象的形式存储在数据库中,而对象之间的关系通过每个对象自身的属性来决定。
(1) High performance - 高并发读写
(2) Huge Storage - 海量数据的高效率存储和访问
(3) High Scalability && Hig Availability - 高可扩展性和高可用性
(1) 键值 (Key - Value) 存储
(2) 列存储
(3) 文档数据库
(4) 图形数据库
(1) 易扩展:数据库种类多,非关系
(2) 灵活的数据模型:无需对存储的数据模型进行建立
(3) 大数据量,高性能:具有高读写性能
(4) 高可用:可以集成于很多框架
REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfillippo 写的 key-value 存储系统,遵循 BSD 协议、支持网络、可基于内存亦可持久化的日志型、 key-value 数据库,通常称它为数据结构服务器,因为值 (value) 可以是 String 、 Hash 、 List 、 Set 、 Sorted Set 等类型。
(1) 缓存:数据的查询
(2) 任务队列:秒杀,抢购
(3) 网站访问统计
(4) 数据过期处理:精确到毫秒
(5) 应用排行榜
(6) 分布式集群架构中的 session 分离
Jedis 是 Redis 官方推荐的 Java 连接开发工具。
// 1.设置IP地址和端口 Jedis jedis = new Jedis("localhost", 6379); // 2.保存数据 jedis.set("name", "张三"); String val = jedis.get("name"); System.out.println(val); // 3.关闭资源 jedis.close();
基于连接池的连接
// 获得连接池的配置对象 JedisPoolConfig config = new JedisPoolConfig(); // 设置最大连接数 config.setMaxTotal(30); // 设置最大的空闲连接数 config.setMaxIdle(10); // 设置最大等待时间 config.setMaxWaitMillis(1000); try( // 获得连接池 JedisPool jedisPool = new JedisPool(config, "localhost", 6379); Jedis jedis = jedisPool.getResource(); ) { jedis.set("name1","00001"); String val = jedis.get("name1"); System.out.println(val); }catch (Exception e){ e.printStackTrace(); }
有关 redis 的下载安装请查考 https://www.runoob.com/redis/redis-install.html
W indow :
Redis 的配置文件位于 Redis 安装目录下文件名为 redis.windows.conf 中,也可以通过 config 命令查看或设置配置项。
redis 127.0 . 0.1 : 6379 > CONFIG GET CONFIG_SETTING_NAME
可以使用 * 号获取所有配置项: config get *
(1) 存: set key1 value1
(2) 取: get key1
(3) 获取并设置: getSet key1 value2
(4) 删除: del key1
(5) 递增: incr key1 ( 将 key1 的值递增一次,如果不存在这个值,则先将这个值设置为 0 ,然后递增 1 ;如果不能转为整形,则返回错误信息。 )
(6) 递减: decr key1 ( 将 key1 的值递减一次,如果不存在这个值,则先将这个值设置为 0 ,然后递减 1 ;如果不能转为整形,则返回错误信息。 )
(7) 递增值: incrby key1 val1 ( 将 key1 的值递增 val1 ,如果不存在这个值,则先将这个值设置为 0 ,然后递增 val1 ;如果不能转为整形,则返回错误信息。 )
(8) 递减值: decrby key1 val1 ( 将 key1 的值递减 val1 ,如果不存在这个值,则先将这个值设置为 0 ,然后递减 val1 ;如果不能转为整形,则返回错误信息。 )
(9) 拼凑字符串: append key1 val1 ( 字符串拼接,将 redis 中 key1 的值后面拼接一个 val1 字符串,返回拼接后字符串的长度,如果不存在,则进行创建设置为 val1)
2. 哈希 (hash) : hash 是一个键值对集合,是 string 类型的 field 和 value 的映射表, hash 特别适合用于存储对象。
(1) 存:存 单个键值对 - hset key1 field1 value1 存多个键值对 - hmset key1 field1 value1 field2 value2 ... ...
(2) 取:取单个键值 - hget key1 field1 取多个键值 - hmget key1 field1 field2 ... ... 取 key1 对象的全部键值 - hgetall key1
(3) 删除:删除多个键值对 - hdel key1 field1 field2 ... 删除全部 del key1
3. 列表 (List) : list 是一个简单字符串列表,按照插入顺序排序。
(1) 两端添加:左侧 - lpush list1 value1 右侧 - rpush list1 value2
(2) 查看: lrange list1 start_number end_number (num 可以为负数,负数表示从尾部开始的索引位置 )
(3) 两端弹出:左侧 - lpop list1 右侧 - rpop list1
(4) 长度: llen list1
(5) 插入: lpushx list1 value1 ( 仅当 list1 存在时才在左侧插入 ) rpushx list1 value1 ( 仅当 key1 存在时才在右侧插入 )
(6) 删除指定值得元素: lrem list1 count_number value1 ( 删除 list1 中 count_number 个值为 value1 的元素,如果 count_number > 0 ,表示从左侧开始多少个;如果 count_number < 0 ,表示从右侧开始多少个;如果 count_number = 0 ,表示全是全部值为 value1 的元素。 )
(7) 在指定位置添加元素:在指定位置插入元素 - lset list1 index1 value1 在指定元素前插入元素 - linsert list1 before value1 value2 在指定元素后插入元素 - linsert list1 after value1 value2
(8) 将 list1 中的尾部元素取出并添加到 list2 的头部 : rpoplpush list1 list2
4. 集合 (Set) : set 是 string 类型的无序集合, set 集合中不允许出现重复的元素。添加一个 string 元素到 key 对应的 set 集合中,成功返回 1 ,如果元素已经在集合中返回 0 ,如果 key 对应的 set 不存在则返回错误。
(1) 存: sadd set1 value1 value2 ...
(2) 查看: smembers set1
(3) 删除: srem set1 value1 value2 ...
(4) 判断在集合中元素是否存在: sismember myset value1 ( 如果存在,返回 1 ;不存在返回 0)
(5) 差集: sdiff set1 set2 ( 返回在 set1 中存在的,在 set2 不存在的元素 )
(6) 交集: sinter set1 set2 ( 返回同时 set1 、 set2 中都存在的元素 )
(7) 并集: sunion set1 set2 ( 返回 set1 、 set2 的集合,会自动去重 )
(8) 获取元素个数: scard set1
(9) 随机返回一个元素: srandmember set1
(10) 将两个 set(set1 、 set2) 的差集存放在另一个集合 (set3) 中: sdiffstore set1 set2 set3
(11) 将两个 set(set1 、 set2) 的交集存放在另一个集合 (set3) 中: sinterstore set1 set2 set3
(12) 将两个 set(set1 、 set2) 的并集存放在另一个集合 (set3) 中: sunionstore set1 set2 set3
5. 有序集合 zset(Sorted set) : zset 和 set 一样也是 string 类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个 double 类型的分数。 Redis 正是通过分数来为集合中的成员进行排序。
(1) 添加元素: zadd sort1 score1 value1 score2 value2 ... ... ( 返回添加元素的个数 )
(2) 获取元素:获取元素的分数 - zscore sort1 value1 获取元素的个数 - zcard sort1
(3) 删除元素: zrem sort1 value1 value2 ... 范围删除 - zremrangebyrank sort1 num1 num2 按分数范围删除 - zremrangebyscore sort1 score1 score2
(4) 范围查找: zrange sort num1 num2 显示分数 - zrange sort1 num1 num2 withscores ( 分数由小到大 ) zreverange sort1 num1 num2 withscores ( 分数由大到小 ) 按分数由小到大查找 - zrangebyscore sort1 num1 num2 按分数由小到大查找,并显示分数 - zrangebyscore sort1 num1 num2 withscores 分页查找 - zrangebyscore sort1 num1 num2 limit start_num stop_num
(5) 分数加减: zscore sort1 score1 value1
(6) 统计分数范围的元素个数: zcount sort1 score1 score2
(1) 获取所有 key : keys *
(2) 获取字符开头的 keys : keys prefix?
(3) 删除 key : del key1 key2 ...
(4) 判断是否存在: exists key1 ( 返回 1- 存在, 0- 不存在 )
(5) 重命名: rename key1 new_key1
(6) 设置过期时间 ( 单位: s) : expire key1 num
(7) 所剩时间: ttl key1 ( 无设置过期时间,返回 -1)
(8) 获取类型: type key1
(1) 指定连接那个数据库: select index_
(2) 将 key1 移动到另一个数据库: move key1 index_
2. R edis 事务 : 事务中,所有命令都会串行执行,事务执行期间, redis 不会为其它的客户端提供服务,从而保证命令原子化执行 。 Redis 命令在事务中可能会执行失败,但是 Redis 事务不会回滚,而是继续会执行余下的命令。这里和关系型数据库有点区别,因为关系型数据在这种情况下都是会回滚的;在 multi 之后的事务语句,都会将事务放进队列,这是会检查语法等,也就是在事务执行期间语法都是没有问题的,命令出错的话就是程序有问题, redis 不会因为一条错误而设计成回滚,降低存储效率来弥补程序本身的错误 。redis 使用的是串行化隔离机制,串行化机制规定事务的提交必须有序的,如果一个事务打开了,未提交事务或者回滚事务,另外开启一个事务的话,必须等待前一个事务处理完数据,才能处理数据,否则后面这个事务不能处理数据,所以后提交的数据时会出现锁为获取或者未获取锁无法提交等等错误。
(1) 开启事务: multi
(2) 提交事务: exec
(3) 回滚事务: discard
Redis 的持久化 :
redis 的高性能是因为所有的数据都是保存在内存中。为了保存数据不被丢失,就需要对数据进行持久化。
1 、 redis 的数据库只包含一个文件,对于文件备份来说很完美
2 、备份: 如 每个小时归档一次最近 24 小时的数据,同时每天归档一次最近 30 天的数据,那么当系统出现灾难性故障的时候,可以恢复(对于灾难恢复来说 RDB 是非常好的选择,可以将一个单独的文件压缩后转移到其他的存储介质上)
3 、性能最大化:对于 redis 进程而言,在开始持久化的时候,它唯一需要做的是 分叉处 一些子进程,之后的由子进程完成这些持久化的工作,极大的避免服务器进程执行 IO 操作
4 、与 AOF 相比优势:启动效率更高
1 、想保证数据的高可用性(最大限度避免数据的丢失),那 RDB 不是一个很好的选择(如果系统在定时持久化之前发生故障,那么数据还没来得及往磁盘上写,数据就已经丢失了)
2 、子进程协助完成持久化,因此当数据集很大的时候,可能会导致服务器停止几百毫秒
redis 默认使用 RDB 方式持久化 , 配置文件为 redis.conf(window 下为 redis.windows-service.conf)
1 、更高的数据安全性 。同步策略:每秒同步,每修改同步、不同步。每秒同步:异步完成,效率高,系统出现宕机,那么这一秒中修改的数据就会丢失;每修改同步:可以看作同步持久化,么一次发生数据的变化,都会立即写到磁盘当中,效率低,但是最安全
2 、对日志文件的写入操作,采用的是追加模式( append ),因此在写入过程中,即使出现了宕机的情况,也不会破坏日志文件中已经存在的内容。如果本次写入进行到一半就出现宕机,那么这种方式也不必担心, redis 在下一次启动之前,可以通过 redis-check-aof 这个工具,帮助我们解决数据一致性的问题
3 、如果日志过大, redis 可以自动启动重写机制, redis 以 append 模式不断的将修改的数据写入到老的磁盘文件当中,同时 redis 会创建一个新的文件,用于记录此期间产生的哪些修改命令被执行。因此,在进行重写切换的时候,可以更好的去保证数据的安全性
4 、 AOF 包含一个格式清晰易于理解的日志文件用于记录所有的修改操作,也可以通过这个文件完成数据的重建
1 、对于相同数量的数据集而言, AOF 的文件要比 RDB 的文件大一些
2 、根据同步策略的不同, AOF 在效率上往往低于 RDB
redis 配置文件为 redis.conf(window 下为 redis.windows-service.conf)
AOF 下的 Redis 持久化 :启动后, 插入一些数据后,通过 flushall 清空数据库 , 然后关闭 redis ,重新启动 redis 之前,修改 日志文件 配置文件,将最后一行的 flushAll 删除,并保存 , 然后重启 redis