redis logfile为空_关于Redis(二)
发布日期:2021-06-24 16:33:13 浏览次数:4 分类:技术文章

本文共 7300 字,大约阅读时间需要 24 分钟。

事务  


在MySQL中事务的四大特性,ACID。原子性、一致性、隔离性、持久性。Redis单条命令保证原子性,但是Redis事务不能保证原子性。Redis事务的本质是一组命令的集合,一组命令就像被放入一个队列,按顺序执行,在执行的过程中其中一条失败其他的也会执行,而且命令都会被序列化。(Redis的事务特性一次性、顺序性、排他性。没有隔离级别的概念)

      Redis事务的执行过程:

  • 开启事务(multi)

  • 命令入队

  • 执行事务 (exec)

  • 放弃事务 (discard)

    73faa543e6f461db03d11f4f635d193e.png

    执行后事务自动关闭。

    在事务执行过程中遇到异常

    • 编译型异常,事务中的命令都不会被执行。

      8ea63d20a696d3a3357ce1d2fc7c7632.png

    • 运行时异常,其他命令都会正常执行。

      75567140e194f7b750d5b06ddfa8fb91.png

Redis实现乐观锁


悲观锁:很悲观,认为肯定会出问题,所以一开始就加锁,如synchronized关键字底层。

乐观锁:很乐观,认为一般情况下不会出问题,所以不开始不加锁,每次更新数据时判断一下,修改过才加锁。

正常执行成功,使用监视器监视key:

c123c41f70f3c75b366d67f7809beaf1.png

在加锁后,如果另一个线程操作了事务中的值,执行事务就会失败,此时需要unwatch再watch重新加锁。

Jedis


redis官方推荐的java连接开发工具 。

c2bb859574be9f5252fd26d979c83014.png

b04d67866be4bc47fe316ef279f10dcb.png

操作api跟命令行一样。

SpringBoot-redis


创建项目,加入依赖。

dcc3379a87e2cc3639225ff39579279a.png

springboot 2.x后 redis连接从jedis改成了lettuce,因为jedis是直连(Bio模式),多个线程连接不安全。而lettuce底层采用Netty,实例可以在多个线程中进行共享,不存在线程不安全的情况。可以减少线程数量(Nio模式)。

  • 导入依赖

8f2c641b5cb0071af8b407685d65ccc4.png

  • 配置连接

    ac5fa53a43012a578d99b7a46f4c1773.png

  • 导入redisTemplate,执行具体的操作,opsForXXX对应的是各种数据类型的操作。

    5b519dd5669ce03428a95c3199968b9c.png

自定义RedisTemplate


@Configurationpublic class LettuceRedisConfig {
   @Resource    private RedisProperties redisProperties;    /**     * 配置RedisTemplate     * @return 返回一个可以使用的RedisTemplate实例     */    @Bean    public RedisTemplate
redisTemplate(RedisConnectionFactory redisConnectionFactory) {
       RedisTemplate
redisTemplate = new RedisTemplate<>();        redisTemplate.setConnectionFactory(redisConnectionFactory);        //设置序列化方式 key采用String序列化 value采用json序列化        redisTemplate.setKeySerializer(new StringRedisSerializer());        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());        redisTemplate.afterPropertiesSet();        return redisTemplate;   }}

Redis.conf详解

b6531b3048db2ef6729f9d23af9646f6.png

UNIT:对大小写不敏感

INCLUDES:引入其他配置文件

NETWORK:网络

# 绑定ipbind 127.0.0.1# 保护模式protected-mode yes# 端口port 6379

GENERAL:通用配置

# 后台运行 默认为no daemonize yes# 以后台方式运行,需要指定一个进程文件 pidfile /var/run/redis_6379.pid# 日志# Specify the server verbosity level.# This can be one of:# debug (a lot of information, useful for development/testing)# verbose (many rarely useful info, but not a mess like the debug level)# notice (moderately verbose, what you want in production probably)# warning (only very important / critical messages are logged)loglevel notice# 日志文件的位置logfile ""# 数据库的数量  默认16databases 16# 是否显示logoalways-show-logo yes

SNAPSHOTTING:开启redis持久化后,持久化文件的配置。

# 持久化规则save 900 1 # 900s内,至少一个key进行了修改,则进行持久化操作save 300 10 # 300s内,至少10个key进行了修改,则进行持久化操作save 60 10000 # 60s内,至少10000个key进行了修改,则进行持久化操作# 持久化出错 是否继续工作stop-writes-on-bgsave-error yes# 是否压缩rdb文件,需要消耗cpu资源rdbcompression yes# 保存rdb文件出错,是否修复rdbchecksum yes# rdb文件保存的目录dir ./

REPLICATION:复制

SECURITY:安全

# 设置密码(修改配置文件)默认为空requirepass "123456"# 设置密码 (命令模式)config set requirepass "123456"# 验证权限auth "123456"

CLIENTS:客户端

# 设置连接客户端的最大数量maxclients 10000# 配置最大的内存容量maxmemory # 内存到达上限的处理策略maxmemory-policy noeviction    - 移除过期key    - 报错

maxmemory-policy 六种方式

1、volatile-lru:只对设置了过期时间的key进行LRU(默认值)

2、allkeys-lru : 删除lru算法的key  

3、volatile-random:随机删除即将过期key  

4、allkeys-random:随机删除  

5、volatile-ttl : 删除即将过期的  

6、noeviction : 永不过期,返回错误

APPEND ONLY MODE:aof配置

# 默认不开启 使用rdb持久化方式appendonly no# 文件名appendfilename "appendonly.aof"# aof持久化周期# appendfsync always # 每次修改都会写入,消耗性能appendfsync everysec # 每秒一次,可能会丢失一秒的数据# appendfsync no

持久化——RDB


RDB概述:在指定的时间间隔内将数据写入磁盘,类似于虚拟机生成快照,恢复的时候将文件直接读取到内存中。

工作原理:Redis会fork一个子进程进行持久化,会将数据写入一个临时的文件中,持久化结束后,新的临时文件替换上一次的临时文件。整个过程中redis主进程不进行任何IO操作。

优点:

  • 如果需要进行大规模的数据恢复,且对数据的完整性不敏感,那么RDB比AOF方式更加高效。

  • 只有一个文件,方便备份和移动。

  • 可以最大化redis的性能,主进程只需要fork一个子进程,不需要任何IO操作。

缺点:

  • 数据可能不完整,当需要保存数据的时间间隔较大且时间较长时,这期间发生宕机,数据就会丢失。

  • 在数据集庞大时,fork子进程耗时。

文件名为dump.rdb。触发规则:满足save配置或执行了flushall命令或退出redis。

如何恢复rdb文件?

  • 将dump.rdb文件放在redis的启动目录下即可。

    查看目录:config get dir

0c8978f0d826e708f2d44507534940ff.png

持久化——AOF


AOF概述:以日志的形式记录每个写操作。

工作原理:在配置文件中开启aof后,每次的写命令都会被追加到appendonly.aof文件中,默认使用的策略是everysec,每秒追加一次,此外还有两种策略,alwaysNO,前者是服务器每写入一个命令,就调用一次fdatasync,这种模式下不会丢失任何已经执行成功的命令数据;后者是服务器不主动调用fdatasync,由操作系统决定任何将缓冲区里面的命令写入磁盘里面,在这种模式写,服务器遭遇意外停机时,丢失命令的数据是不确定的。redis启动时会读取appendonly.aof文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

优点:

  • 数据完整性较好,不易丢失数据,即使丢,也最多是一秒的数据。

缺点:

  • 性能较差

  • 文件数据大

  • 恢复速度慢

3cc286ae5634c82b08cb19c35cfd4cdb.png

aof重写:redis中的数据时有限的,很多数据可能过期或被删除,但是这些命令都会被aof记录下来,当文件越来越大,恢复的shi'h没必要执行所有aof文件中记录的命令,所以出现了rewrite策略,在redis2.4之前,需要手动执行bgrewriteaof来重写aof,之后提供了自动rewrite的策略,在配置文件中开启aof重写机制后,当aof文件达到配置的大小,就会fork一个子进程来执行rewrite操作,往一个新的临时的aof文件中写入日志,主进程接收到client新的写操作后,在内存中写入日志,同时新的日志也继续写入旧aof文件,子进程写完新的日志文件后,redis主进程将内存中的新日志再次追加到新的aof文件中,最后用新的aof文件替换旧的aof文件。

当aof文件被破坏时,可以使用redis-check-aof --fix命令修复文件。

以下内容摘自:简书

作者:mkdlp链接:https://www.jianshu.com/p/050b526cf6ce

RDB和AOF同时工作

因为redis的持久化操作是非常消耗性能的,那么当他们俩发生冲突的时候会怎么办?

(1)如果RDB在执行snapshotting操作,那么redis不会执行AOF rewrite; 如果redis再执行AOF rewrite,那么就不会执行RDB snapshotting

(2)如果RDB在执行snapshotting,此时用户执行BGREWRITEAOF命令,那么等RDB快照生成之后,才会去执行AOF rewrite

(3)同时有RDB snapshot文件和AOF日志文件,那么redis重启的时候,会优先使用AOF进行数据恢复,因为其中的日志更完整

(4)在有rdb的dump和aof的appendonly的同时,rdb里也有部分数据,aof里也有部分数据,这个时候其实会发现,rdb的数据不会恢复到内存中

大家也可做个小实验,将aof中的数据删除一条(这条数据已经持久化到rdb中),然后用redis的修复工具进行修复,在用这个文件替换aof文件,重启redis,最后会发现rdb中的数据不会被恢复到内存中。

redis的数据恢复完全是依赖于底层的磁盘的持久化的,如果rdb和aof上都没有数据,那就真的没了。

4.在实际项目的使用中,我们应该如何配置和使用呢?

(1).配置策略

   在企业级的项目中,我们使用rdb的默认配置也无大碍,即:

save 900 1

save 300 10

save 60 10000

   唯一可能要调整的就是 save 60 10000 这个检查点,因为rdb的生成还是比较耗费资源的,如果说低峰期数据量很小,那么也没太大必要。但是如果你要保证RDB最多丢一分钟的数据,那么剩下的就是你自己根据实际情况去配置,到底是一分钟-10000生成rdb,还是说设置成1分钟-1000生成rdb。

 aof的话这里推荐把他打开,调用fsync的策略推荐使用everysec,然后根据你项目的实际情况去设置以下两个属性:

auto-aof-rewrite-percentage 100 这个属性改的必要也不是特别的大

auto-aof-rewrite-min-size 64mb 这个根据你的数据量来定

(2).数据备份方案

RDB的话是非常适合做冷备的,每次RDB生成完成之后就不会再修改了,备份的方案可以这样:

(a).写crontab定时调度脚本去做数据备份

(b).每小时都copy一份rdb的备份,到一个目录中去,仅仅保留最近48小时的备份

(c).每天都保留一份当日的rdb的备份,到一个目录中去,仅仅保留最近1个月的备份

(d).每次copy备份的时候,都把太旧的备份给删了

(e).每天晚上将当前服务器上所有的数据备份,发送一份到远程的云服务上去

每小时copy一次备份,删除48小时前的数据

crontab -e0 * * * * sh /usr/local/redis/copy/redis_rdb_copy_hourly.shredis_rdb_copy_hourly.sh
\#!/bin/shcur_date=`date +%Y%m%d%k`rm -rf /usr/local/redis/snapshotting/$cur_datemkdir /usr/local/redis/snapshotting/$cur_datecp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_datedel_date=`date -d -48hour +%Y%m%d%k`rm -rf /usr/local/redis/snapshotting/$del_date

每天copy一次备份

crontab -e0 0 * * * sh /usr/local/redis/copy/redis_rdb_copy_daily.shredis_rdb_copy_daily.sh
\#!/bin/shcur_date=`date +%Y%m%d`rm -rf /usr/local/redis/snapshotting/$cur_datemkdir /usr/local/redis/snapshotting/$cur_datecp /var/redis/6379/dump.rdb /usr/local/redis/snapshotting/$cur_datedel_date=`date -d -1month +%Y%m%d`rm -rf /usr/local/redis/snapshotting/$del_date

每天一次将所有数据上传一次到远程的云服务器上去

(3).数据恢复方案

(a).如果是redis进程挂掉,那么重启redis进程即可,直接基于AOF日志文件恢复数据。

(b).如果是redis进程所在机器挂掉,那么重启机器后,尝试重启redis进程,尝试直接基于AOF日志文件进行数据恢复。AOF没有破损,也是可以直接基于AOF恢复的,如果AOF文件出现了破损,则用redis的修复工具修复之后在进行恢复。

(c).如果redis当前最新的AOF和RDB文件出现了丢失/损坏,那么可以尝试基于该机器上当前的某个最新的RDB数据副本进行数据恢复。

(d).如果当前机器上的所有RDB文件全部损坏,那么从远程的云服务上拉取最新的RDB快照回来恢复数据。

(e).如果是发现有重大的数据错误,比如某个小时上线的程序一下子将数据全部污染了,数据全错了,那么可以选择某个更早的时间点,对数据进行恢复。

(4).基于RDB冷备恢复数据

   基于rdb冷备其实是有一些小坑的,这里拿出来记录一下,如果你同时打开RDB和AOF,如果你使用的是AOF的冷备去恢复数据,那么很简单,将redis的aof文件替换成你的冷备然后重启redis就行了。

   但是要是你使用的是RDB的冷备,你首先要把redis现有的aof文件删掉,然后把rdb文件替换成你的冷备,但是由于你开着aof,所以在aof启动的时候会直接生成一份空的aof文件,而你的RDB冷备会被无视掉,过了一段时间可能会被重写掉。你可能会想,那我们把AOF关掉不就行了吗?我们把AOF关掉,重启redis,确实,RDB的数据会被恢复到redis中,现在数据回来了,但是AOF不能关掉,所以你再次修改配置文件打开AOF重启redis,这时你发现辛辛苦苦恢复的数据又没了,其实还是因为打开AOF重新生成了一份空的AOF文件,RDB里面就算有数据也不会恢复到redis当中。那么怎么解决呢?我们可以通过热修改redis属性的方式进行恢复,我们先把redis的AOF关掉,用RDB冷备恢复数据,在redis-cli 中使用 config set 指令来开启AOF,等RDB冷备的数据全被写入AOF后,再修改配置文件打开AOF,重启redis即可。以下是具体的流程:

(a).停止redis

(b).关闭aof

(c).拷贝rdb备份

(d).重启redis,确认数据恢复

(e).直接在命令行热修改redis配置,打开aof,redis就会将内存中的数据对应的日志,写入aof文件中

(f).此时aof和rdb两份数据文件的数据就同步了

转载地址:https://blog.csdn.net/weixin_33865450/article/details/113580058 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:mysql 设计两个主键都不可重复_程序员面试备战篇:18个经典MySQL面试专题解析(干货分享答案)...
下一篇:python双击py一闪_Python脚本在双击.py时无法正常运行

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月23日 08时47分03秒