十念 发表于 2024-11-27 06:50:53

Redis

Redis

windows版Redis启动方式

https://i-blog.csdnimg.cn/direct/e80fc76a0c5e4679b0bb017d1357d1d6.jpeg#pic_center
然后输入redis-server redis.windows.conf 启动乐成后如下图所示
https://i-blog.csdnimg.cn/direct/3a2ee900a20a407d8274572ee8a3e594.jpeg#pic_center
ctrl+c取消毗连
redis.conf文件

绑定主机地址 bind IP 默认是本机,只能本机访问(远程访问毗连为0.0.0.0)
https://i-blog.csdnimg.cn/direct/b292644f1381491a90d15638a821a853.jpeg#pic_center
设置服务器端口号 port 默认6379
https://i-blog.csdnimg.cn/direct/91ca626249154a599c1dbc0bbba02882.jpeg#pic_center
假如端口号为默认端口号6379,再打开一个终端,输入redis-cli 然后输入ping 它会出现PONG说明毗连乐成
假如不是默认端口,需要输入redis-cli -p 端口号
https://i-blog.csdnimg.cn/direct/ddb9e61db31145019e653aae934f5522.jpeg#pic_center
设置服务器文件保存地址 dir path
maxclients 设置最大毗连数
https://i-blog.csdnimg.cn/direct/fc6d9d46f50b45d7a24d427135d6d553.jpeg#pic_center
https://i-blog.csdnimg.cn/direct/e0563491334f4911959a82e2eb87af4f.jpeg#pic_center
把maxclients设置为1
然后,ctrl+c取消毗连,再重新输入redis-server redis.windows.conf 启动,然后再另一个终端输入ping ,然后输入info clients
查看当前的毗连数量为1
https://i-blog.csdnimg.cn/direct/f65841cbc53b4809b1d2246cc5aed56f.jpeg#pic_center
然后再重新打开一个终端
https://i-blog.csdnimg.cn/direct/4ab974266b364ad2b93103f5de28ce94.jpeg#pic_center
凌驾了最大毗连数
Redis基本操作

redis中以key——value的形式存储
https://i-blog.csdnimg.cn/direct/bae214b0941040aaa85ecb158f089d65.jpeg#pic_center
Redis数据范例(常用的4种)

string 、hash、list、set
在学习sting这个数据形式之前,我们先要明白sting到底是修饰什么的。我们知道redis 自身是一个 Map,其中所有的数据都是采用 key-value 的形式存储。对于这种布局来说,我们用来存储数据肯定是一个值前面临应一个名称,我们通过名称来访问背面的值,按照这种形势,我们可以对出来我们的存储格式。前面这一部分我们称为key。背面的一部分称为value,而我们的数据范例,他肯定是修饰value的。
数据范例指的是存储的数据的范例,也就是 value 部分的范例,key 部分永远都是字符串。
string数据范例

添加/修改数据 set key value
获取数据 get key
删除数据del key
https://i-blog.csdnimg.cn/direct/d8f577b75f674b55aa9b99d119feaf42.jpeg#pic_center
判断性添加数据 setnx key value(仅在键不存在时才设置该键。SETNX是 “Set if Not Exists”(假如不存在则设置)的缩写)
https://i-blog.csdnimg.cn/direct/c88a40265e7b4f3fbd5225328a64b13a.jpeg#pic_center
添加/修改多个数据 mset key1 value1 key2 value2.
获取多个数据mget key1 key2 …
获取数据字符个数(字符串长度)strenkey
追加信息到原始信息后部(假如原始信息存在就追加,否则新建)append key value
https://i-blog.csdnimg.cn/direct/13fbcbd6892548fbbc51c3861d9a666b.jpeg#pic_center
string范例数据的扩展操作

string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
对数字进行操作:
incr key (是要进行自增操作的键名,每次执行 INCR 命令,键的值都会增长1,并返回自增后的值。)
https://i-blog.csdnimg.cn/direct/363fcb35240e4cddbcf3bb504bb79b35.jpeg#pic_center
incrby key increment (自定义自增 Incrby 命令将 key 中储存的数字加上指定的增量值,假如 key 不存在,那么 key 的值会先被初始化为0 ,然后再执行INCRBY 命令)
https://i-blog.csdnimg.cn/direct/8e92f8cb65534780b130785b93f6a2ba.jpeg#pic_center
incrbyfloat key increment(指定浮点数进行自增)
https://i-blog.csdnimg.cn/direct/214c7c3b3ad14957927f6af13d8f5606.jpeg#pic_center
设置数值数据减少指定范围的值 decr key
decrby key increment(Decrby 命令将 key 所储存的值减去指定的减量值。假如key不存在,那么key 的值会先被初始化为0然后再执行DECRBY 操作)
https://i-blog.csdnimg.cn/direct/05020d398c144275947c9b3a894135d4.jpeg#pic_center
设置数据具有指定的生命周期
setex key seconds value(设置key对应字符串value,并且设置key在给定的seconds时间之后超时逾期)
psetex key miliseconds value(设置key对应的value,并设置key的逾期时间为miliseconds 毫秒之后)
https://i-blog.csdnimg.cn/direct/10640093306d4b62b15744ce9e774885.jpeg#pic_center
注意事项

(1)数据操作不乐成的反馈与数据正常操作之间的差异
表现运行结果是否乐成
(integer) 0 ==》false 失败
(integer) 1 ==》 true 乐成
表现运行结果值
(integer)3 ==》3 3个
(integer)1 == 》1 1个
(2)数据未获取到时,对应的数据为(nil),等同于nul
(3)数据最大存储量:512MB
(4)string在redis内部存储默认就是一个字符串,当遇到增减类操作incr,decr时会转成数值型进行计算
(5)按数值进行操作的数据,假如原始数据不能转成数值,或超越了redis数值上限范围,将报错9223372036854775807(iava中long型数据最大值,Long.MAX VALUE)
(6)redis所有的操作都是原子性的,采用单线程处置惩罚所有业务,命令是一个一个执行的,因此无需考虑并发带来的数据影响
string应用场景与key定名约定

应用场景

它的应用场景在于:主页高频访问信息表现控制,例如新浪微博大V主页表现粉丝数与微博数量。
我们来思考一下:这些信息是不是你进入大V的页面儿以后就要读取这写信息的啊,那这种信息肯定要存储到我们的redis中,因为他的访问量太高了!那这种数据应该怎么存呢?我们来一块儿看一下方案!
解决方案

(1)在redis中为大V用户设定用户信息,以用户主键和属性值作为key,后台设定定时刷新计谋即可。
eg: user: id: 506728370 fans–> 12210947
eg: user: id: 3506728370 blogs -->6164
eg: user: id: 3506728370 focuses–> 83
(2)也可以使用json格式保存数据
eg: user: id:3506728370 --> {"fans”:12210947,“blogs”:6164,"focuses ":83 }
(3)key 的设置约定
数据库中的热点数据key定名惯例
表名主键名主键值字段名eg1orderid2433535nameeg2equipid2424455typeeg3newsid3234656title hash范例

新的存储需求:对一系列存储的数据进行编组,方便管理,典型应用存储对象信息
需要的存储布局:一个存储空间保存多个键值对数据
hash范例:底层使用哈希表布局实现数据存储
左边一个key,对右边一个存储空间。这里要明白一点,右边这块儿存储空间叫hash,也就是说hash指的是一个数据范例,他指的不是一个数据,是这里边的一堆数据,那么它底层呢,是用hash表的布局来实现的。
值得注意的是:
假如field数量较少,存储布局优化为类数组布局
假如field数量较多,存储布局使用HashMap布局
hash的基本操作

添加/修改数据
hset key field value
https://i-blog.csdnimg.cn/direct/b125462398624521aa1fb969443e894c.jpeg#pic_center
获取数据
hget key field
hgetall key
https://i-blog.csdnimg.cn/direct/88b329fefbdc4145a0015812ed0651c5.jpeg#pic_center
删除数据
hdel key field1
https://i-blog.csdnimg.cn/direct/704a2fe369a94b9e8fc6b73af7951bb9.jpeg#pic_center
设置field的值,假如该field存在则不做任何操作
hsetnx key field value
https://i-blog.csdnimg.cn/direct/2f72c5b4e71f4da796f3410a687cfe53.jpeg#pic_center
添加/修改多个数据
hmset key field1 value1 field2 value2
https://i-blog.csdnimg.cn/direct/f6c3b2ce8bbe44d18743e30f636b8ebc.jpeg#pic_center
获取多个数据
hmget key field1 field2
https://i-blog.csdnimg.cn/direct/2d3e683538a94a11a81c971509e1eb08.jpeg#pic_center
获取哈希表中字段的数量
hlen key
获取哈希表中是否存在指定的字段
hexists key field
https://i-blog.csdnimg.cn/direct/f0cbde51fdef4b60a02684a4af27d101.jpeg#pic_center
hash 范例数据扩展操作

获取哈希表中所有的字段名或字段值
hkeys key
hvals key
设置指定字段的数值数据增长指定范围的值
hincrby key field increment
hincrbyfloat key field increment
https://i-blog.csdnimg.cn/direct/6ee5c47468d849bd8ab2bfcc52359e27.jpeg#pic_center
hash范例数据操作的注意事项

(1)hash范例中value只能存储字符串,不允许存储其他数据范例,不存在嵌套现象。假如数据未获取到,对应的值为(nil)。2,第个在能人星对复篇:2?2的,?出用,严深。心在对象的教播方,并且可以灵活添加删除对象属性。但hash设计初衷
(3)hgeta 操作可以获取全部属性,假如内部field过多,遍历团体数据服从就很会低,有可能成为数据访问瓶颈。
hash应用场景

双11活动日,销售手机充值卡的商家对移动、联通、电信的30元、50元、100元商品推出抢购活动,每种商品抢购上限1000 张。
也就是商家有了,商品有了,数量有了。终极我们的用户买东西就是在改变这个数量。那你说这个布局应该怎么存呢?对应的商家的ID作为key,然后这些充值卡的ID作为feld,最后这些数量作为value。而我们所谓的操作是实在就是increa这个操作,只不外你传负值就行了。看一看对应的解决方案:
解决方案
以商家id作为key
将参与抢购的商品id作为field
将参与抢购的商品数量作为对应的value
抢购时使用降值的方式控制产物数量
list范例

前面我们存数据的时间呢,单个数据也能存,多个数据也能存,但是这里面有一个题目,我们存多个数据用hash的时间它是没有顺序的,。我们平时操作,现实上数据很多情况下都是有顺序的,那有没有一种能够用来存储带有顺序的这种数据模型呢,list就专门来干这事儿。
数据存储需求:存储多个数据,并对数据进入存储空间的顺序进行区分需要的
存储布局:一个存储空间保存多个数据,且通过数据可以体现进入顺序
list范例:保存多个数据,底层使用双向链表存储布局实现
list范例数据基本操作

添加/修改数据
lpush key value1 …(注意lpush第一位为小写的L)左边添加
rpush key value1 … 右边添加
获取数据(注意lrange第一位为小写的L)
lrange key start stop(返回存储在 key 的列表里指定范围内的元素。start 和 end 偏移量都是基于0的下标,即list的第一个元素下标是0(list的表头),第二个元素下标是1,以此类推,偏移量也可以是负数,表现偏移量是从list尾部开始计数。 例如,-1表现列表的最后一个元素,-2 是倒数第二个,以此类推)
lindex key index(返回列表 key 中,下标为 index 的元素。)
llen key(返回当前列表key的长度。当key不存在时返回0)
获取并移除数据
Ipop key(移除并返回表头(左侧)的元素。当key不存在时,返回nil)
https://i-blog.csdnimg.cn/direct/42842a719d2948ab8e97fd2493256789.jpeg#pic_center
list扩展操作

移除指定数据
lrem key count value
注意:Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相称的元素。COUNT 的值可以是以下几种:
count>0:从表头开始向表尾搜索,移除与 VALUE 值类似的元素,移除数量为 COUNT
count <0:从表尾开始向表头搜索,移除与 VALUE 值类似的元素,移除数量为 COUNT 的绝对值。
count=0:移除表中所有与 VALUE 值类似的元素。
https://i-blog.csdnimg.cn/direct/33ec246cca534ca597518f3680682fd7.jpeg#pic_center
规定时间内获取并移除数据
blpop key1timeout (移出并获取列表的第一个元素,假如列表没有元素会阻塞列表直超时或发现可弹出元素为止)参数说明:
。key1 : 至少一个列表范例的键名,假如多个键名,BLPOP按照key1,key2,…keyN的顺序查找非空列表进行弹出操作。
timeout: 超时时间,单位为秒。假如timeout为0,即阻塞时间为0,则BLPOP命令将会一直阻塞,直到有非空列表能够弹出,否则当前毗连一直阻塞。
https://i-blog.csdnimg.cn/direct/edbd0eba077b4353b42e07fc8c65422d.jpeg#pic_center
此时会阻塞,然后我们再打开一个终端,
https://i-blog.csdnimg.cn/direct/5f185a4d0a1a44f88f0926777ba91ead.jpeg#pic_center
然后发现上一个移除完成
https://i-blog.csdnimg.cn/direct/56973d1d67d74daabd3865f9a0be0b57.jpeg#pic_center
brpop key1 timeout 右移除,基本操作同上
brpoplpush source destination timeout(命令从列表中取出最后一个元素,并插入到另外一个列表的头部; 假如列表没有元素会阻塞列表直到等候超时或发现可弹出元素为止)
https://i-blog.csdnimg.cn/direct/1f4b8b0167214bf399a570db546b6d3f.jpeg#pic_center
会阻塞(上图为阻塞消失后的终极结果),打开另一个终端
https://i-blog.csdnimg.cn/direct/c78a3b65ff9e49b1bdd91e7f425c2608.jpeg#pic_center
前面的阻塞会消失,如上图
set范例

set范例:与hash存储布局完全类似,仅存储键,不存储值(nil),并且值是不允许重复的
set范例基本操作

添加数据:sadd key member1
获取全部数据:smembers key
删除数据: srem key member1
获取聚集数据总量:scard key
判断聚集中是否包含指定数据:sismember key member
https://i-blog.csdnimg.cn/direct/5c1b851cd9a440c0bc5f5c5d9a327aec.jpeg#pic_center
随机获取聚集中指定数量的数据: srandmember key
随机获取聚集中某个数据并将该数据移除聚集:spop key
https://i-blog.csdnimg.cn/direct/422fd917c41940558d5e865beaaf93ae.jpeg#pic_center
set范例数据扩展操作

求两个聚集的交 并 差集
sinter key1 交集
sunion key1 合集
sdiff key1 差集(在前面的为参照)
https://i-blog.csdnimg.cn/direct/94a8bda2466f40338165a8fb913cfa24.jpeg#pic_center
求两个聚集的交、并、差集并存储到指定聚集中
sinterstore destination key1
(将key1 与key2的合集放入destination destination可以更改为其他名字)
sunionstore destination key1
sdiffstore destination key1
将指定数据从原始聚集中移动到目标聚集中
smove source destination member
https://i-blog.csdnimg.cn/direct/4759661fe4ce4623be5e7b8421e0c31f.jpeg#pic_center
set范例数据操作的注意事项

set 范例不允许数据重复,假如添加的数据在 set 中已经存在,将只保留一份
set 虽然与hash的存储布局类似,但是无法启用hash中存储值的空间
常用指令

key基本操作

删除指定的key del key
获取key是否存在 exists key
获取key的范例 type key
排序 sort key:返回值从小到大排序的结果
​ sort key desc:返回键值从小到大的排序结果
改名 rename key newkey(假如newkey已经存在,那么该命令将会用oldkey的值覆盖newkey的值)
​ renamenx key newkey(命令用于在新的key不存在时修改key的名称)
https://i-blog.csdnimg.cn/direct/d5c6b6a6973a4a1f877ae6d80431fa14.jpeg#pic_center
key扩展操作(时效性控制)

为指定key设置有效期
expire key seconds(设置逾期时间为多少秒)
pexpire key milliseconds(设置逾期时间为多少毫秒)
expireat key timestamp (用于将键key的逾期时间设置为timestamp所指定的秒数时间戳。)
pexpireat key miiseconds-timestamp (用于将键key的逾期时间设置为timestamp所指定的毫秒数时间戳。)
https://i-blog.csdnimg.cn/direct/16e2915d77a949f0ac21a0d0c69d02be.jpeg#pic_center
ttl key 获取key的有效时间
假如key不存在或者已逾期,返回-2
假如key存在并且没有设置逾期时间(永世有效),返回-1。
pttl key 用于获取一个键的剩余逾期时间,以毫秒为单位。
假如键不存在或已逾期,则返回-2.
假如键没有关联到逾期时间,则返回-1
persist key 切换key从时效性转换为永世性exists
https://i-blog.csdnimg.cn/direct/cfdff35e22c34289870c8f0de2295d5a.jpeg#pic_center
key 扩展操作(查询模式)

查询key
keys pattern查询模式规则
匹配任意数量的任意符号 *
配合一个任意符号 ?
匹配一个指定符号 [ ]
keys * 查询所有
keys it* 查询所有以it开头
keys *buka 查询所有以buka结尾
keys ??buka 查询所有前面两个字符任意,背面以buka结尾
keys user:? 查询所有以user:开头,最后一个字符任意
keys uer:1 查询所有以u开头,以er:1结尾,中间包含一个字母,s或t
数据库指令

key重复题目

在这个地方我们来讲一下数据库的常用指令,在讲这个东西之前,我们先思考一个题目:假如说你们十个人同时操作redis,会不会出现key名字定名冲突的题目。
肯定会,为什么?因为你的key是由程序而定义的。你想写什么写什么,那在使用的过程中大家都在不绝的加,早晚有一天他会冲突的,。
redis在使用过程中,陪同着操作数据量的增长,会出现大量的数据以及对应的key。
那这个题目我们要不要解决?要!怎么解决呢?我们最好把数据进行一个分类,除了定名规范我们做统一以外,假如还能把它分开,这样是不是冲突的机率就会小一些了
redis为每个服务提供有16个数据库,编号从0到15
每个数据库之间的数据相互独立
在对应的数据库中划出一块地区,说他就是几,你就用几那块,同时,其他的这些都可以进行定义,一共是16个,这里边需要注意一点他们这16个共用redis的内存。没有说谁大谁小,也就是说数字只是代表了一块儿地区,地区具体多大未知。这是数据库的一个分区的一个计谋!
https://i-blog.csdnimg.cn/direct/f6d2c06e705c40a8bbb05a082c82b316.jpeg#pic_center
数据库基本操作

切换数据库 select index
https://i-blog.csdnimg.cn/direct/8098fc0c85a447a59b5205b161f7f18d.jpeg#pic_center
数据移动 move key db
将当前数据库的 key 移动到给定的数据库 db 当中。
数据总量 dbsize
数据扫除 flushdb(清空当前库的数据)
https://i-blog.csdnimg.cn/direct/50269ff9a83f4622bb3b4b614ab8661e.jpeg#pic_center
实时监控指令MONITOR

MONITOR是一个Redis的内置命令,用于实时监控Redis服务器上执行的所有命令和活动。当我们执行这个命令时,Redis会立即返回个实时的事件流,表现所有传入的命令以及它们的执行时间
https://i-blog.csdnimg.cn/direct/cd373ef0cbba430e8d2add41ac90ec7b.jpeg#pic_center
注意事项:
性能影响:MONITOR命令会斲丧肯定的CPU和内存资源。在生产环境中使用时,需要谨慎考虑其对性能的影响。
数据安全:因为MONITOR会输出所有执行的命令,包括可能包含敏感信息的命令(如AUTH),所以在使用时需要特殊注意数据安全。
单一职责:当redis-cli进入MONITOR模式后,它不能执行其他Redis命令。
Jedis

我们要使用Java来操作Redis
什么是Jedis?是Redis官方推荐的Java毗连开发工具!使用Java操作Redis中间件!
1、导入对应依赖

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>2.9.0</version>
</dependency>
2、编码测试



[*] 毗连数据库
[*] 操作命令
[*] 断开毗连
package com.buka;

import redis.clients.jedis.Jedis;

public class TestPing {
    public static void main(String[] args) {
      //1、 new Jedis对象
      Jedis jedis = new Jedis("127.0.0.1",6379);
      //jedis 所有的命令就是我们之前学习的说有指令
      System.out.println(jedis.ping());
    }
}
输出 PONG
SpringBoot集成redis

引入依赖
<parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-parent</artifactId>
      <version>2.3.4.RELEASE</version>
      <relativePath/> <!-- lookup parent from repository -->
    </parent>

<dependencies>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.4.RELEASE</version>
      </dependency>
      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.3.4.RELEASE</version>
      </dependency>

      <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
      </dependency>

    </dependencies>
配置application.yml
server:
port: 8080

spring:
redis:
    host: localhost
    port: 6379
import org.springframework.web.bind.annotation.RestController;

@RestController
public class RedisController {
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @RequestMapping("/get/{key}")
    public String test(@PathVariable("key") String key){
      return stringRedisTemplate.opsForValue().get(key);
    }
}

package com.buka.redisspringboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RedisSpringBootApplication {
    public static void main(String[] args) {
      SpringApplication.run(RedisSpringBootApplication.class,args);
    }
}
SpringBoot实现共享Session

在使用SpringBoot做负载平衡的时间,多个app之间的session要保持同等,这样负载到差别的app时间,在一个app登录之后,而访问到另外一台服务器的时间,session丢失,在开发Springboot app的时间可以借助spring session和redis来存储session的状态,包管多个app之间可以实现session的共享
创建两个应用,并且引入相干的依赖

创建SpringBootStudy和SpringBoot1应用,并导入相干的依赖
<!--配置spring session data redis的依赖-->
<dependency>
    <groupId>org.springframework.session</groupId>
    <artifactId>spring-session-data-redis</artifactId>
    <version>2.0.2.RELEASE</version>
</dependency>

编写相应代码和配置

创建配置文件,开启共享session的功能,在主类添加@EnableRedisHttpSession
在yaml中编写相干配置
spring:
redis:
    port: 6379
    host: localhost
session:
    redis:
      namespace: spring:session#保存session的名称空间
    store-type: redis   #存储的介质为redis
编写测试代码
在一个SpringBoot项目中向session中设置值
package com.buka.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class SessionController {
    @RequestMapping("/getSession")
    public String getSession(HttpSession httpSession){
       return String.valueOf(httpSession.getAttribute("user"));
    }
}
在另一个SpringBoot项目中从session中获取值(注意这个项目也要开启RedisSession共享)
package com.buka.redisspringboot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpSession;

@RestController
public class SessionController {
    @RequestMapping("/setSession")
    public String setSession(HttpSession httpSession){
      httpSession.setAttribute("user","zhangsan");
      return "ok";
    }
}
启动项目并且测试

发送请求设置值:
https://i-blog.csdnimg.cn/direct/17a7899f883b46ed8b11243558fb3c8c.jpeg#pic_center
查看redis数据库:
https://i-blog.csdnimg.cn/direct/081ffac08a444ec3a0d3c58584e76cdb.jpeg#pic_center
可以看到session有关的信息都已经保存进redis中
发送获取session值的请求:
https://i-blog.csdnimg.cn/direct/631cfc5e45b548cdbff665252ae48735.jpeg#pic_center
可以获取到对应的session的值
持久化

什么是持久化

(1)什么是持久化
使用永世性存储介质将数据进行保存,在特定的时间将保存的数据进行规复的工作机制称为持久化
持久化用于防止数据的不测丢失,确保数据安全性。
(2)持久化过程保存什么?
我们知道一点,计算机中的数据全部都是二进制,假如现在我要你给我保存一组数据的话,你有什么样的方式呢,实在最简单的就是现在长什么样,我就记下来就行了,那么这种是记载纯粹的数据,也叫做快照存储,也就是它保存的是某一时候的教据状态。
还有一种形式,它不记载你的数据,它记载你所有的操作过程,比如说大家用idea的时间,有没有遇到过写错了ctl+z撤销,然后ctlty还能规复,这个地方它也是在记载,但是记载的是你所有的操作过程,那我想问一下,操作过程,我都给你留下来了,你说数据还会丢吗?肯定不会丢,因为你所有的操作过程我都保存了。这种保存操作过程的存储,用专业术语来说可以说是日志,这是两种差别的保存数据的形式啊。
总结一下:
第一种:将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据
第二种:将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程。
save配置自动执行

设置自动持久化的条件,满足限定时间范围内key的变化数量达到指定数量即进行持久化
second changessave
参数
second:监控时间范围
changes:监控key的变化量范例:
save 3600 1
save 300 10
save 60 10000
其他相干配置:
dbfilename filename
dir path
rdbcompression yes|no
rdbchecksum yes|no
stop-writes-on-bgsave-error yes|no
RDB两种启动方式对比

方式save指令bgsave指令读写同步异步阻塞客户端指令是否额外内存斲丧否是启动新线程否是 RDB特殊启动形式

服务器运行过程中重启
debug reload
关闭服务器时指定保存数据
shutdown save全量复制(在主从复制中详细解说)
RDB优点:

RDB是一个紧凑压缩的二进制文件,存储服从较高
RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
RDB规复数据的速度要比AOF快很多
应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程呆板中,用于劫难规复。
RDB缺点:

RDB方式无论是执行指令照旧使用配置,无法做到实时持久化,具有较大的可能性丢失数据。
bgsave指令每次运行要执行fork操作创建子历程,要牺牲掉一些性能
Redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本服务之间数据格式无法兼容现象.
AOF

为什么要有AOF,这得从RDB的存储的弊端说起:
存储数据量较大,服从较低,基于快照思想,每次读写都是全部数据,当数据量巨大时,服从非常低.
大数据量下的IO性能较低
基于fork创建子历程,内存产生额外斲丧。
岩机带来的数据丢失风险
那解决的思绪是什么呢?
不写全数据,仅记载部分数据低落区分数据是否改变的难度,改记载数据为记载操作过程.
对所有操作均进行记载,排除丢失数据的风险
AOF概念

AOF(append ony e)持久化:以独立只志的方式记载每次写命令,重启时再重新执行AOF文件中命令 达到规复数据的目的。与RDB根比可以简单理解为由记载数据改为记载数据产生的变化
AOF的紧张作用是解决了数据持久化的实时性,现在已经是Redis持久化的主流方式
启动AOF相干配置

开启AOF持久化功能,默认no,即不开启状态
appendonly yes|no
AOF持久化文件名,默认文件名为appendonly.aof,建议配置为appendonly-端口号.aof
appendfilename filename
AOF持久化文件保存路径,与RDB持久化文件保持同等即可
dir
AOF写数据计谋,默以为everysec
appendfsync always|everysec|no
AOF执行计谋

AOF写数据三种计谋(appendfsync)
always(每次):每次写入操作均同步到AOF文件中数据零误差,性能较低,不建议使用。
everysec(每秒):每秒将缓冲区中的指令同步到AOF文件中,在体系忽然宕机的情况下丢失1秒内的数据 数据准确性较高,性能较高,建议使用,也是默认配置
no(体系控制):由操作体系控制每次同步到AOF文件的周期,团体过程不可控
AOF重写

什么叫AOF重写?

随着命令不断写入AOF,文件会越来越大,为了解决这个题目,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis历程内的数据转化为写命令同步到新AOF文件的过程。简单说就是将对同一个数据的若干个条命令执行结果转化成终极结果数据对应的指令进行记载。
AOF重写作用

低落磁盘占用量,进步磁盘使用率
进步持久化服从,低落持久化写时间,进步IO性能.
低落数据规复用时,进步数据规复服从
AOF重写规则

历程内具有时效性的数据,并且数据已超时将不再写入文件
非写入类的无效指令将被忽略,只保留终极数据的写入命令.
如del key1、hdel key2、srem key3、set key4 111、set key5 222等
如select指令虽然不更改数据,但是更改了数据的存储位置,此类命令同样需要记载
对同一数据的多条写命令归并为一条命令
如lpush list1 a、lpush list1 b、lpush list1 c可以转化为:lpush list1 a b c。
为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等范例,每条指令最多写入64个元素
AOF重写方式

手动重写 bgrewriteaof
自动重写
auto-aof-rewrite-min-size size
指定了触发AOF重写的最小AOF文件大小,当当前AOF文件大小凌驾这个值时,Redis会自动触发AOF重写操作。该参数的默认值为64MB,假如不盼望Redis自动触发AOF重写操作,可以将该值设置为0.
auto-aof-rewrite-percentage percentage
配置了当 aof 文件相较于上一版本的 aof 文件大小的百分比达到多少时触发 AOF 重写
自动重写触发条件设置
auto-aof-rewrite-min-size size
auto-aof-rewrite-percentage percent
自动重写触发比对参数
aof_current_size
aof_base_size
自动触发与AOF重写配置几个参数有关
1)auto-aof-rewrite-min-size:AOF文件重写需要的最小的大小。就是说当AOF文件至少多大要积的时间在开始进行重写,默认64M。
2)auto-aof-rewrite-percentage:AOF文件增长率,当进行过了一次重写,下一次进行重写的时间看这个AOF文件的增长率,默认100。
3)aof current size:当前AOF文件的大小(单位:字节)。
4)aof base size:上一次操作或者重写后的AOF文件大小(单位:字节)。
RDB与AOF对比(优缺点)

持久化方式RDBAOF占用存储空间小(数据级:压缩)大(指令级:重写)存储速度慢快规复速度快慢数据安全性会丢失数据依据计谋决定资源斲丧高/重量级低/轻量级启动优先级低高 RDB与AOF应用场景

RDB与AOF的选择之惑

对数据非常敏感,建议使用默认的AOF持久化方案
AOF持久化计谋使用evervsecond,每秒钟fsvnc一次。该计谋redis仍可以保持很好的处置惩罚性能,当出 现题目时,最多丢失0-1秒内的数据。
注意:由于AOF文件存储体积较大,且规复速度较慢
数据呈现阶段有效性,建议使用RDB持久化方案
数据可以精良的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且规复速度较快,阶段点数据规复通常采用RDB方案注意:使用RDB实现紧凑的数据持久化会使Redis降的很低,慎重
总结

综合比对

RDB与AOF的选择现实上是在做一种权衡,每种都有利有弊
如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF.
如能承受数分钟以内的数据丢失,且寻求大数据集的规复速度,选用RDB.
劫难规复选用RDB
双保险计谋,同时开启 RDB和 AOF,重启后,Redis优先使用 AOF 来规复数据,低落丢失数据的量.

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: Redis