专栏首页黑泽君的专栏大数据技术之_21_Redis学习_02_解析 Redis 配置文件 redis.conf + Redis 的持久化 + Redis 的事务 + Redis 的复制(Master/Slave)+ Re

大数据技术之_21_Redis学习_02_解析 Redis 配置文件 redis.conf + Redis 的持久化 + Redis 的事务 + Redis 的复制(Master/Slave)+ Re

第四章 解析 Redis 配置文件 redis.conf

4.1 Units 单位

1、配置大小单位,开头定义了一些基本的度量单位,只支持 bytes(字节),不支持 bit(位数)。 2、对大小写不敏感。

4.2 INCLUDES 包含

指定包含其它的配置文件,可以在同一主机上多个 Redis 实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件。 include /path/to/local.conf

4.3 GENERAL 通用

daemonize pidfile port

bind timeout

loglevel logfile databases

4.4 SNAPSHOTTING 快照

sava

RDB是整个内存的压缩过的Snapshot,RDB的数据结构,可以配置复合的快照触发条件。
默认
save 900 1
save 300 10
save 60 10000

15分钟内改了1次,就保存一次快照
或5分钟内改了10次,就保存一次快照
或1分钟内改了1万次,就保存一次快照

注意:实际开发中 30 分钟保存一次快照。

如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以。
sava ""

stop-writes-on-bgsave-error 默认配置是yes,表示在使用bgsave命令备份的时候出现错误则停止外界写入操作, 如果配置成no,表示你不在乎数据不一致或者有其他的手段发现和控制。 dbfilename dir dump.rdb存储的目录,即启动redis时的目录

4.5 SECURITY 安全

具体操作如下:

4.6 LIMITS 限制

maxclients

  设置 redis 同时可以与多少个客户端进行连接。默认情况下为 10000 个客户端。当你无法设置进程文件句柄限制时,redis 会设置为当前的文件句柄限制值减去 32,因为 redis 会为自身内部处理逻辑留一些句柄出来。如果达到了此限制,redis 则会拒绝新的连接请求,并且向这些连接请求方发出 “max number of clients reached” 以作回应。 maxmemory   设置 redis 可以使用的内存量。一旦到达内存使用上限,redis 将会试图移除内部数据,移除规则可以通过 maxmemory-policy 来指定。如果 redis 无法根据移除规则来移除内存中的数据,或者设置了“不允许移除”,那么 redis 则会针对那些需要申请内存的指令返回错误信息,比如 SET、LPUSH 等。   但是对于无内存申请的指令,仍然会正常响应,比如 GET 等。如果你的 redis 是主 redis(说明你的 redis 有从 redis),那么在设置内存使用上限时,需要在系统中留出一些内存空间给同步队列缓存,只有在你设置的是“不移除”的情况下,才不用考虑这个因素。 maxmemory-policy   •(1)volatile-lru:使用 LRU 算法移除 key,只对设置了过期时间的键   •(2)allkeys-lru:使用 LRU 算法移除 key   •(3)volatile-random:在过期集合中移除随机的 key,只对设置了过期时间的键   •(4)allkeys-random:移除随机的 key   •(5)volatile-ttl:移除那些 TTL 值最小的 key,即那些最近要过期的 key   •(6)noeviction:不进行移除。针对写操作,只是返回错误信息,实际开发中不使用这个配置。

4.7 APPEND ONLY MODE 追加

appendonly appendfilename appendfsync   always:同步持久化,每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好。   everysec:出厂默认推荐,异步操作,每秒记录,如果一秒内宕机,有数据丢失,实际开发中推荐   no

4.8 常见配置 redis.conf 介绍

参数说明:

redis.conf 配置项说明如下:
1. Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程
  daemonize no
2. 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定
  pidfile /var/run/redis.pid
3. 指定 Redis 监听端口,默认端口为 6379,作者在自己的一篇博文中解释了为什么选用 6379 作为默认端口,因为 6379 在手机按键上是 MERZ 对应的号码,而 MERZ 取自意大利歌女 Alessia Merz 的名字
  port 6379
4. 绑定的主机地址
  bind 127.0.0.1
5.当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
  timeout 300
6. 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 verbose
  loglevel verbose
7. 日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null
  logfile stdout
8. 设置数据库的数量,默认数据库为 0,可以使用 SELECT <dbid> 命令在连接上指定数据库 id
  databases 16
9. 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
  save <seconds> <changes>
  Redis 默认配置文件中提供了三个条件:
  save 900 1
  save 300 10
  save 60 10000
  分别表示 900 秒(15分钟)内有 1 个更改,300 秒(5分钟)内有 10 个更改以及 60 秒内有 10000 个更改。
10. 指定存储至本地数据库时是否压缩数据,默认为 yes,Redis 采用 LZF 压缩,如果为了节省 CPU 时间,可以关闭该选项,但会导致数据库文件变的巨大
  rdbcompression yes
11. 指定本地数据库文件名,默认值为 dump.rdb
  dbfilename dump.rdb
12. 指定本地数据库存放目录
  dir ./
13. 设置当本机为 slave 服务时,设置 master 服务的 IP 地址及端口,在 Redis 启动时,它会自动从 master 进行数据同步
  slaveof <masterip> <masterport>
14. 当 master 服务设置了密码保护时,slave 服务连接 master 的密码
  masterauth <master-password>
15. 设置 Redis 连接密码,如果配置了连接密码,客户端在连接 Redis 时需要通过 AUTH <password> 命令提供密码,默认关闭
  requirepass foobared
16. 设置同一时间最大客户端连接数,默认无限制,Redis 可以同时打开的客户端连接数为 Redis 进程可以打开的最大文件描述符数,如果设置 maxclients 0,表示不作限制。当客户端连接数到达限制时,Redis 会关闭新的连接并向客户端返回 max number of clients reached 错误信息
  maxclients 128
17. 指定 Redis 最大内存限制,Redis 在启动时会把数据加载到内存中,达到最大内存后,Redis 会先尝试清除已到期或即将到期的 key,当此方法处理 后,仍然到达最大内存设置,将无法再进行写入操作,但仍然可以进行读取操作。Redis 新的 vm 机制,会把 key 存放内存,value 会存放在 swap 区
  maxmemory <bytes>
18. 指定是否在每次更新操作后进行日志记录,Redis 在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。因为 redis 本身同步数据文件是按上面 save 条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为 no
  appendonly no
19. 指定更新日志文件名,默认为 appendonly.aof
   appendfilename appendonly.aof
20. 指定更新日志条件,共有3个可选值: 
  no:表示等操作系统进行数据缓存同步到磁盘(快) 
  always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全) 
  everysec:表示每秒同步一次(折衷,默认值)
  appendfsync everysec
21. 指定是否启用虚拟内存机制,默认值为 no,简单的介绍一下,VM机制将数据分页存放,由Redis将访问量较少的页即冷数据swap到磁盘上,访问多的页面由磁盘自动换出到内存中(在后面的文章会仔细分析 Redis 的 VM 机制)
  vm-enabled no
22. 虚拟内存文件路径,默认值为 /tmp/redis.swap,不可多个 Redis 实例共享
  vm-swap-file /tmp/redis.swap
23. 将所有大于 vm-max-memory 的数据存入虚拟内存,无论 vm-max-memory 设置多小,所有索引数据都是内存存储的(Redis的索引数据 就是 keys),也就是说,当 vm-max-memory 设置为0的时候,其实是所有 value 都存在于磁盘。默认值为 0
  vm-max-memory 0
24. Redis swap 文件分成了很多的 page,一个对象可以保存在多个 page 上面,但一个 page 上不能被多个对象共享,vm-page-size 是要根据存储的 数据大小来设定的,作者建议如果存储很多小对象,page 大小最好设置为 32 或者 64bytes;如果存储很大大对象,则可以使用更大的 page,如果不确定,就使用默认值
  vm-page-size 32
25. 设置 swap 文件中的 page 数量,由于页表(一种表示页面空闲或使用的 bitmap)是在放在内存中的,,在磁盘上每 8 个 pages 将消耗 1byte 的内存。
  vm-pages 134217728
26. 设置访问 swap 文件的线程数,最好不要超过机器的核数,如果设置为 0,那么所有对 swap 文件的操作都是串行的,可能会造成比较长时间的延迟。默认值为 4
  vm-max-threads 4
27. 设置在向客户端应答时,是否把较小的包合并为一个包发送,默认为开启
  glueoutputbuf yes
28. 指定在超过一定的数量或者最大的元素超过某一临界值时,采用一种特殊的哈希算法
  hash-max-zipmap-entries 64
  hash-max-zipmap-value 512
29. 指定是否激活重置哈希,默认为开启(后面在介绍 Redis 的哈希算法时具体介绍)
  activerehashing yes
30. 指定包含其它的配置文件,可以在同一主机上多个 Redis 实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
  include /path/to/local.conf

第五章 Redis 的持久化

RBD小结

AOF小结

第六章 Redis 的事务

Redis 事务常用命令:

Redis 的事务脑图

第七章 Redis 的复制(Master/Slave)

第八章 Redis 的 Java 客户端 Jedis

测试连通性

package com.atguigu.test;

import redis.clients.jedis.Jedis;

public class HelloRedis {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.25.102", 6379);

        String result = jedis.ping();

        System.out.println("**********" + result);

        // Connection
    }
}

五大数据类型 + 1个 key

package com.atguigu.test;

import java.util.Set;

import redis.clients.jedis.Jedis;

public class APIRedis {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("192.168.22.167", 6379);

        Set<String> set = jedis.keys("*");
        System.out.println(set.size());

        jedis.set("k3", "v3");

        System.out.println(jedis.get("k3"));
    }
}

事务提交

package com.atguigu.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Transaction;

public class TXRedis {

    public boolean transMethod() throws InterruptedException {
        Jedis jedis = new Jedis("192.168.25.102", 6379);

        int balance;// 可用余额
        int debt;// 欠额
        int amtToSubtract = 10;// 实刷额度

        jedis.watch("balance");
        Thread.sleep(8000); // 停止程序一小段时间,外面先修改balance数据后看效果
        balance = Integer.parseInt(jedis.get("balance"));

        if (balance < amtToSubtract) {
            jedis.unwatch();
            System.out.println("The Data has been updated before you commit or balance < amtToSubtract");
            return false;
        } else {
            System.out.println("***********transaction");

            Transaction transaction = jedis.multi();
            transaction.decrBy("balance", amtToSubtract);
            transaction.incrBy("debt", amtToSubtract);
            transaction.exec();

            balance = Integer.parseInt(jedis.get("balance"));
            debt = Integer.parseInt(jedis.get("debt"));

            System.out.println("*******" + balance);
            System.out.println("*******" + debt);
            return true;
        }
    }

    /**
     * 伪代码如下: 通俗点讲,watch 命令就是标记一个键,如果标记了一个键:
     * 
     * 在提交事务前如果该键被别人修改过,那事务就会失败,这种情况通常可以在程序中重新再尝试一次。
     * 首先标记了键balance,然后检查余额是否足够,不足就取消标记,并不做扣减; 足够的话,就启动事务进行更新操作,
     * 如果在此期间键balance被其它人修改, 那在提交事务(执行exec)时就会报错, 程序中通常可以捕获这类错误再重新执行一次,直到成功。
     * 
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        TXRedis test = new TXRedis();
        boolean retValue = test.transMethod();
        System.out.println("main retValue-------: " + retValue);
    }
}

主从复制

package com.atguigu.test;

import redis.clients.jedis.Jedis;

public class ReplicationRedis {

    public static void main(String[] args) {
        Jedis jedisM = new Jedis("192.168.25.102", 6379);
        Jedis jedisS = new Jedis("192.168.25.102", 6380);

        jedisS.slaveof("192.168.25.102", 6379);

        jedisM.set("k3", "v3");

        String result = jedisS.get("k3");

        System.out.println("############# result: " + result);
    }
}

JedisPoolUtils.java

package com.atguigu.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

public class JedisPoolUtils {
    private static volatile JedisPool jedisPool = null;

    private JedisPoolUtils() {
    }

    // DCL(double check lock)
    public static JedisPool getInstance() {
        if (null == jedisPool) {
            synchronized (JedisPoolUtils.class) {
                if (null == jedisPool) {
                    JedisPoolConfig poolConfig = new JedisPoolConfig();
                    poolConfig.setMaxActive(100);
                    poolConfig.setMaxIdle(32);
                    poolConfig.setMaxWait(100 * 1000);
                    poolConfig.setTestOnBorrow(true);

                    jedisPool = new JedisPool(poolConfig, "192.168.25.102", 6379);
                }
            }
        }
        return jedisPool;
    }

    public static void close(JedisPool jedisPool, Jedis jedis) {
        if (null != jedis) {
            jedisPool.returnResourceObject(jedis);
        }
    }
}

JedisPoolRedis.java

package com.atguigu.test;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

public class JedisPoolRedis {

    public static void main(String[] args) {
        JedisPool jedisPool = JedisPoolUtils.getInstance();
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            jedis.set("k5", "0508good");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JedisPoolUtils.close(jedisPool, jedis);
        }
    }
}

配置总结

JedisPool 的配置参数大部分是由 JedisPoolConfig 的对应项来赋值的。

maxActive:控制一个 pool 可分配多少个 jedis 实例,通过 pool.getResource() 来获取;如果赋值为 -1,则表示不限制;如果  pool 已经分配了 maxActive 个 jedis 实例,则此时 pool 的状态为 exhausted。

maxIdle:控制一个 pool 最多有多少个状态为 idle(空闲) 的 jedis 实例。

whenExhaustedAction:表示当 pool 中的 jedis 实例都被 allocated 完时,pool 要采取的操作,默认有三种:
   WHEN_EXHAUSTED_FAIL  --> 表示无 jedis 实例时,直接抛出 NoSuchElementException
   WHEN_EXHAUSTED_BLOCK --> 则表示阻塞住,或者达到 maxWait 时抛出 JedisConnectionException
   WHEN_EXHAUSTED_GROW --> 则表示新建一个 jedis 实例,也就说设置的 maxActive 无用

maxWait:表示当 borrow 一个 jedis 实例时,最大的等待时间,如果超过等待时间,则直接抛 JedisConnectionException;

testOnBorrow:在 borrow 一个 jedis 实例时,是否提前进行 validate 操作;如果为 true,则得到的 jedis 实例均是可用的;

testOnReturn:在 return 给 pool 时,是否提前进行 validate 操作;

testWhileIdle:如果为 true,表示有一个 idle object evitor 线程对 idle object 进行扫描,如果 validate 失败,此 object 会被从 pool 中 drop 掉;这一项只有在 timeBetweenEvictionRunsMillis 大于0时才有意义;

timeBetweenEvictionRunsMillis:表示 idle object evitor 两次扫描之间要 sleep 的毫秒数;

numTestsPerEvictionRun:表示 idle object evitor 每次扫描的最多的对象数;

minEvictableIdleTimeMillis:表示一个对象至少停留在 idle 状态的最短时间,然后才能被 idle object evitor 扫描并驱逐;这一项只有在 timeBetweenEvictionRunsMillis 大于0时才有意义;

softMinEvictableIdleTimeMillis:在 minEvictableIdleTimeMillis 基础上,加入了至少 minIdle 个对象已经在 pool 里面了。如果为 -1,evicted 不会根据 idle time 驱逐任何对象。如果 minEvictableIdleTimeMillis > 0,则此项设置无意义,且只有在 timeBetweenEvictionRunsMillis > 0 时才有意义;

lifo:borrowObject 返回对象时,是采用 DEFAULT_LIFO(last in first out,即类似 cache 的最频繁使用队列),如果为 False,则表示 FIFO 队列;

=================================================
其中 JedisPoolConfig 对一些参数的默认设置如下:

testWhileIdle=true
minEvictableIdleTimeMills=60000
timeBetweenEvictionRunsMillis=30000
numTestsPerEvictionRun=-1

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • day67_Redis学习笔记_01

    添加spring的jar包 配置spring配置文件applicationContext.xml applicationContext.xml

    黑泽君
  • day72_淘淘商城项目_05_匠心笔记

    taotao-portal-web工程中,动态展示内容信息。 前端团队:负责JS,html等开发。 后端团队:负责后台的开发并提供数据给前端。

    黑泽君
  • day67_Redis学习笔记_03

      上边的配置说明当前该【从redis服务器】所对应的【主redis服务器】的IP是192.168.5.128,端口是6379。

    黑泽君
  • HBase Thrift2 CPU过高问题分析

    外界连接9090端口均超时,但telnet端口总是成功。使用top命令观察,发现单个线程的CPU最高达99.99%,但并不总是99.9%,而是在波动。当迁走...

    一见
  • AI系统实现了自动编程,程序员要被取代了吗?

    随着人工智能技术的快速进展,人工智能时代的序幕已经揭起,目前深度学习在图像处理方面的能力已经接近于人,甚至在某些方面已经超过人的识别能力。在语音识别、自然语言处...

    疯狂的技术宅
  • 如何从挫败感到成就感,身为程序员每天都在经历这些!

    IT故事会
  • 如何在CoreOS集群上使用CloudSlang清理Docker环境

    CoreOS是一个Linux发行版,专注于利用Docker容器和服务查询快速启动集群环境。但是,Docker镜像可能占用Docker主机上相当多的磁盘空间。普通...

    宇cccc
  • 钱塘解析 | 2015年全国电力工业统计数据报告

    电力是以电能作为动力的能源。它的发明和应用掀起了第二次工业化高潮。成为人类历史18世纪以来,世界发生的三次科技革命之一,从此科技改变了人们的生活。20世纪出现的...

    钱塘数据
  • 动态 | 谷歌大脑新奇发现:分类误差为零的模型就不存在对抗性样本了

    AI 科技评论按:谷歌大脑近期的一篇新论文对对抗性样本做了多方面的理论性研究,不仅首次发现了简单数据分布下对抗性样本的分布特性,而且得出了「分类误差为零的模型不...

    AI科技评论
  • css+ js 实现圆环时钟

    小蔚

扫码关注云+社区

领取腾讯云代金券