From bbccd0696119523ad12b63001efa519a81cffbf2 Mon Sep 17 00:00:00 2001 From: Byron4j <1552546443@qq.com> Date: Tue, 21 May 2019 18:37:23 +0800 Subject: [PATCH] =?UTF-8?q?Redis=E6=A0=8F=E7=9B=AE=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...-Maven-profile\351\205\215\347\275\256.md" | 128 ++ README.md | 10 +- ...30\346\261\260\347\255\226\347\225\245.md" | 14 + ...0\345\205\265-\345\244\215\345\210\266.md" | 22 + ...-Redis-Cluster\351\233\206\347\276\244.md" | 21 + ...is\346\214\201\344\271\205\345\214\226.md" | 22 + ...72\346\231\257\345\210\206\346\236\220.md" | 52 + ...30\346\226\271\345\216\237\345\247\213.md" | 1388 ++++++++++++++++ ...07\344\273\266\350\247\243\346\236\220.md" | 1415 +++++++++++++++++ ...73\347\273\237\345\221\275\344\273\244.md" | 21 + Redis/pictures/1.jpg | Bin 0 -> 32631 bytes Redis/pictures/2.jpg | Bin 0 -> 22527 bytes ...220\257\345\212\250\345\231\250starter.md" | 23 +- .../0-\346\200\273\350\247\210.md" | 3 + ...27\345\217\243\347\256\227\346\263\225.md" | 6 + ...10\345\270\214\347\256\227\346\263\225.md" | 2 + ...70\351\227\256\351\242\230\347\233\256.md" | 9 +- 17 files changed, 3130 insertions(+), 6 deletions(-) create mode 100644 "Maven/2-Maven-profile\351\205\215\347\275\256.md" create mode 100644 "Redis/7-Redis\346\214\201\344\271\205\345\214\226.md" create mode 100644 "Redis/8-Redis\345\272\224\347\224\250\345\234\272\346\231\257\345\210\206\346\236\220.md" create mode 100644 "Redis/9-1Redis-conf\345\256\230\346\226\271\345\216\237\345\247\213.md" create mode 100644 "Redis/9-Redis-conf\351\205\215\347\275\256\346\226\207\344\273\266\350\247\243\346\236\220.md" create mode 100644 "Redis/999-Redis\350\277\220\347\273\264\347\263\273\347\273\237\345\221\275\344\273\244.md" create mode 100644 Redis/pictures/1.jpg create mode 100644 Redis/pictures/2.jpg create mode 100644 "\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/0-\346\200\273\350\247\210.md" create mode 100644 "\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/3-\344\270\200\350\207\264\346\200\247\345\223\210\345\270\214\347\256\227\346\263\225.md" diff --git "a/Maven/2-Maven-profile\351\205\215\347\275\256.md" "b/Maven/2-Maven-profile\351\205\215\347\275\256.md" new file mode 100644 index 0000000..b6c599d --- /dev/null +++ "b/Maven/2-Maven-profile\351\205\215\347\275\256.md" @@ -0,0 +1,128 @@ +# Maven-profile配置 + +用Maven的小伙伴都知道,Maven的宗旨是约定优于配置(Convention Over Configuration)。 + +在宗旨的前提下Maven也提供了个性化定制的Profile,让我们看看用法哈! + +首先让我们一起看看Maven中的属性,这个用的挺多的: + +注:以下属性请在pom文件中使用,项目中使用默认是不支持的需要自己配置。 + + 内置属性: ${basedir}项目根目录 + + ${version} 项目版本号 + + Pom属性: ${project.artifactId} + + ${project.build.sourceDirectory} + + ${project.build.testSourceDirectory} + + ${project.build.directory} + + ${project.outputDirectory} + + ${project.testOutputDirectory} + + ${project.groupId} + + ${project.version} + + ${project.build.finalName} + + 自定义属性:Settings: ${settings.localRepository} ,引用settings.xml文件中的XML元素的值 + + Java系统属性: ${user.home} + + 环境变量属性: ${env.JAVA_HOME} + + +现在我们开始认识Profile,以下是一个简单的Profile结构体: + +```xml + + + dev + + com.mysql.jdbc.Driver + + + +``` + +定义一个id为dev、属性db.driver为com.mysql.jdbc.Driver的Profile。 +仅仅定义就行了吗?答案是否定的。我们需要激活Profile才能生效,我们可以通过```mvn clean install -P dev```激活! + +(注:```dev为激活ID,如果你想激活多个可以mvn clean install -P dev1,dev2使用,如果不想激活某一个用-P!dev1```) + +以上是一种激活方式,下面我们继续介绍其他激活方式 + +activeByDefault默认激活: + +```xml + + + dev + + com.mysql.jdbc.Driver + + + true + + + +``` + +settings.xml默认激活: + +```xml + +... + + dev1 + +... + +``` + + +系统属性激活: + +```xml + + + dev + + com.mysql.jdbc.Driver + + + + test + driver + + + + +``` + +注:上面表示test=driver时才激活, ```mvn clean install -Dtest=driver``` +系统环境激活: + +```xml + + + dev + + com.mysql.jdbc.Driver + + + [1.5,1.8) + + oracle.properties + jdbc.properties + + + + +``` +注:上面表示jdk为1.5、1.6和1.7的时候激活,存在jdbc.properties文件情况,不存在oracle.properties文件情况激活 \ No newline at end of file diff --git a/README.md b/README.md index 1777f91..2bc962e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Tech Stack of Java back-end developer [![Build Status](https://travis-ci.com/Byron4j/fuckjava-thread-concurrency.svg?branch=master)](https://travis-ci.com/Byron4j/fuckjava-thread-concurrency)![APM](https://img.shields.io/apm/l/vim-mode.svg?label=License&style=popout) ![](https://img.shields.io/badge/author-%E4%B8%9C%E9%99%86%E4%B9%8B%E6%BB%87-red.svg) +ma# Tech Stack of Java back-end developer [![Build Status](https://travis-ci.com/Byron4j/fuckjava-thread-concurrency.svg?branch=master)](https://travis-ci.com/Byron4j/fuckjava-thread-concurrency)![APM](https://img.shields.io/apm/l/vim-mode.svg?label=License&style=popout) ![](https://img.shields.io/badge/author-%E4%B8%9C%E9%99%86%E4%B9%8B%E6%BB%87-red.svg) >任何技能通过 “刻意练习” 都可以达到融会贯通的境界,就像烹饪一样,这里有一份JAVA开发技术手册,只需要增加自己练习的次数。 @@ -66,6 +66,7 @@ - 🐶**Maven** - 🐶[编写一个Maven插件](Maven/1-编写一个Maven插件.md) + - [Maven-profile配置](Maven/2-Maven-profile配置.md) - **Jenkins** @@ -91,8 +92,13 @@ - 🍅[Redis内存淘汰策略](Redis/1-Redis内存淘汰策略.md) - 🍅[Redis数据类型以及数据结构实现](Redis/2-Redis数据类型以及数据结构实现.md) - 🍅[Redis缓存](Redis/3-Redis缓存.md) - - 🍅[Redis哨兵](Redis/4-Redis哨兵-复制.md) + - 🍅[Redis哨兵-复制](Redis/4-Redis哨兵-复制.md) - 🍅[Redis-Cluster集群](Redis/5-Redis-Cluster集群.md) + - 🍅[Redis分布式锁](Redis/6-Redis分布式锁.md) + - 🍅[Redis持久化](Redis/7-Redis持久化.md) + - 🍅[Redis应用场景分析](Redis/8-Redis应用场景分析.md) + - 🍅[Redis-conf配置文件解析](Redis/9-Redis-conf配置文件解析.md) + - 🍅[Redis运维系统命令](Redis/999-Redis运维系统命令.md) - 👲RocketMQ - 👲[Windows安装RocketMQ以及运行第一个MQ程序](RocketMQ/0-windows安装RocketMQ以及运行第一个MQ程序.md) - 👲[RocketMQ核心知识](RocketMQ/1-RocketMQ核心知识.md) diff --git "a/Redis/1-Redis\345\206\205\345\255\230\346\267\230\346\261\260\347\255\226\347\225\245.md" "b/Redis/1-Redis\345\206\205\345\255\230\346\267\230\346\261\260\347\255\226\347\225\245.md" index 57ac446..c5aee15 100644 --- "a/Redis/1-Redis\345\206\205\345\255\230\346\267\230\346\261\260\347\255\226\347\225\245.md" +++ "b/Redis/1-Redis\345\206\205\345\255\230\346\267\230\346\261\260\347\255\226\347\225\245.md" @@ -1,5 +1,19 @@ # Redis内存淘汰策略 +## Redis淘汰策略 + +当达到最大内存```maxmemory```限制时,使用```maxmemory-policy```配置指令配置Redis的确切行为。 +配置方式: maxmemory-policy options,默认为 + +- **noeviction**: 不会移除任何key,在写的时候直接返回error +- **volatile-lru** : 使用LRU算法清除过期的key +- **allkeys-lru** : 使用LRU算法清除key +- **volatile-lfu** : 使用LFU算法清除过期的key +- **allkeys-lfu** : 使用LFU算法清除key +- **volatile-random** : 在过期的key中随机移除一个key +- **allkeys-random** : 在所有key中随机移除一个key +- **volatile-ttl** : 移除具有具有最近过期时间的key + - [Redis-缓存](https://redis.io/topics/lru-cache) \ No newline at end of file diff --git "a/Redis/4-Redis\345\223\250\345\205\265-\345\244\215\345\210\266.md" "b/Redis/4-Redis\345\223\250\345\205\265-\345\244\215\345\210\266.md" index e36f761..fac938d 100644 --- "a/Redis/4-Redis\345\223\250\345\205\265-\345\244\215\345\210\266.md" +++ "b/Redis/4-Redis\345\223\250\345\205\265-\345\244\215\345\210\266.md" @@ -91,7 +91,29 @@ sentinel parallel-syncs resque 5 Redis为了解决单点故障问题,会把数据复制到多个副本部署到其他节点,通过数据冗余来实现高可用。 +![](pictures/1.jpg) +- 1. 从redis节点首先发送```sync```到主redis节点 +- 2. 主节点接收到从节点sync命令后;客户端发送写请求时,主节点会```缓存所有的写命令```;然后主节点会```fork子进程生成一个RDB快照``` +- 3. RDB持久化完成后,主节点发送RDB文件和缓存起来的命令给从节点 +- 4. 复制初始化完成后,客户端向主节点写入的每条指令,,主节点接收到后,都会同步的发送到从节点 + +>Redis2.8以后主从断开重连后会根据断开之前最新的命令偏移量进行增量复制。 + + + + +## Redis主从、哨兵、集群之间的差异 + +- **主从**: 读写分离,备份,一个master可以有多个从节点 +- **哨兵**:监控、故障自动转移,烧饼发现主节点挂掉,会从从节点通过raft算法选举一个作为主节点 +- **集群**:将数据按一定规则分配到多台机器,不受限于单机,可以分布式集群扩展。 + +**哨兵目标是高可用;** +**集群目的是提高并发量;** + + + #### 参考资料 diff --git "a/Redis/5-Redis-Cluster\351\233\206\347\276\244.md" "b/Redis/5-Redis-Cluster\351\233\206\347\276\244.md" index e69de29..00f0d08 100644 --- "a/Redis/5-Redis-Cluster\351\233\206\347\276\244.md" +++ "b/Redis/5-Redis-Cluster\351\233\206\347\276\244.md" @@ -0,0 +1,21 @@ +# Redis集群 + +## Redis集群方案有哪些 + +有两种: **codis架构**、**官方的redis cluster**。 + +## codis集群架构 + +codis是豌豆荚基于go编写的redis。 + +## 官方Redis Cluster集群方案 + +![](pictures/2.jpg) + +特点: + +- Redis官网推出的,先行扩展可以达到1000个节点 +- 没有中心架构 +- 一致性哈希思想 +- 客户端直连redis + diff --git "a/Redis/7-Redis\346\214\201\344\271\205\345\214\226.md" "b/Redis/7-Redis\346\214\201\344\271\205\345\214\226.md" new file mode 100644 index 0000000..0568973 --- /dev/null +++ "b/Redis/7-Redis\346\214\201\344\271\205\345\214\226.md" @@ -0,0 +1,22 @@ +# Redis持久化 + +Redis支持两种数据持久化方式: **RDB**、**AOF**。 + +## RDB持久化 + +>根据配置的规则定时将内存中的数据持久化到硬盘上 + +将redis在内存中的数据记录定时dump到磁盘上的RDB持久化。 + +在指定的时间间格里将内存中的数据集快照写入磁盘,实际上是fork一个子进程,先将数据写入临时文件,写入成功后,再替换之前的文件,二进制压缩。 + + + +## AOF持久化 + +>每次执行写命令后将命令记录下来 + +AOF是将redis的操作日志以追加的方式写入文件。 + +和mysql类似,用日志的形式记录服务器的每一个写、删除操作;以文本的方式记录;通过查看该文件可以查看到详细的操作细节。 + diff --git "a/Redis/8-Redis\345\272\224\347\224\250\345\234\272\346\231\257\345\210\206\346\236\220.md" "b/Redis/8-Redis\345\272\224\347\224\250\345\234\272\346\231\257\345\210\206\346\236\220.md" new file mode 100644 index 0000000..8aed46c --- /dev/null +++ "b/Redis/8-Redis\345\272\224\347\224\250\345\234\272\346\231\257\345\210\206\346\236\220.md" @@ -0,0 +1,52 @@ +# Redis应用场景 + +- 计数器 +- 排行榜 +- session +- 发布订阅 +- 消息队列 + +## 实际场景 + +### 页面缓存 + +如果使用的是服务端内容渲染,可以使用redis将经常被请求的内容缓存起来,降低页面请求渲染的延迟 + +### 计数器/排行榜 + +Redis是一个运行在内存中的C程序。 +Redis可以实现快速计数、查询缓存的功能,同时数据可以异步落地到其他数据源。 + +- 访问计数,用户每访问一次,计数就增加1 +- 排行榜: 可以按时间、按数量、按集赞数进行排行 + +### session +用户已经登陆的信息存放在redis中,每次用户更新或查询耕录信息可以直接从redis中获取。 + +### 消息队列 + +利用list数据类型可以构建一个简单高效的队列 + +### 发布订阅 + +pub/sub 是Redis内置的发布订阅功能,可以创建多人在线聊天系统、通知触发等 + + + + + + + + + + + + + + + + + + + + diff --git "a/Redis/9-1Redis-conf\345\256\230\346\226\271\345\216\237\345\247\213.md" "b/Redis/9-1Redis-conf\345\256\230\346\226\271\345\216\237\345\247\213.md" new file mode 100644 index 0000000..28e504a --- /dev/null +++ "b/Redis/9-1Redis-conf\345\256\230\346\226\271\345\216\237\345\247\213.md" @@ -0,0 +1,1388 @@ +-------------------------------------- + +```properties + +# Redis configuration file example. +# +# Note that in order to read the configuration file, Redis must be +# started with the file path as first argument: +# +# ./redis-server /path/to/redis.conf + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include /path/to/local.conf +# include /path/to/other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule /path/to/my_module.so +# loadmodule /path/to/other_module.so + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 127.0.0.1 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +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 + +# Specify the log file name. Also the empty string can be used to force +# Redis to log on the standard output. Note that if you use standard +# output for logging but daemonize, logs will be sent to /dev/null +logfile "/tmp/redis6379.log" + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no + +# Specify the syslog identity. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" + +save 900 1 +save 300 10 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# ------------------------------------------------------- +# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY +# ------------------------------------------------------- +# +# New replicas and reconnecting replicas that are not able to continue the replication +# process just receiving differences, need to do what is called a "full +# synchronization". An RDB file is transmitted from the master to the replicas. +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child producing +# the RDB file finishes its work. With diskless replication instead once +# the transfer starts, new replicas arriving will be queued and a new transfer +# will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple replicas +# will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the server +# waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# Replicas send PINGs to server in a predefined interval. It's possible to change +# this interval with the repl_ping_replica_period option. The default value is 10 +# seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a replica +# wants to reconnect again, often a full resync is not needed, but a partial +# resync is enough, just passing the portion of data the replica missed while +# disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO output. +# It is used by Redis Sentinel in order to select a replica to promote into a +# master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel will +# pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +################################## SECURITY ################################### + +# Require clients to issue AUTH before processing any other +# commands. This might be useful in environments in which you do not trust +# others with access to the host running redis-server. +# +# This should stay commented out for backward compatibility and because most +# people do not need auth (e.g. they run their own servers). +# +# Warning: since Redis is pretty fast an outside user can try up to +# 150k passwords per second against a good box. This means that you should +# use a very strong password otherwise it will be very easy to break. +# +# requirepass foobared + +# Command renaming. +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select among five behaviors: +# +# volatile-lru -> Evict using approximated LRU among the keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU among the keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key among the ones with an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica to have +# a different memory setting, and you are sure all the writes performed to the +# replica are idempotent, then you may change this default (but be sure to understand +# what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory and so +# forth). So make sure you monitor your replicas and make sure they have enough +# memory to never hit a real out-of-memory condition before the master hits +# the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives: + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### +# +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however +# in order to mark it as "mature" we need to wait for a non trivial percentage +# of users to deploy it in production. +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# + +正常的Redis实例不能成为Redis集群的一部分;只有节点是可以作为集群节点启动 + +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes +每一个集群节点都有一个集群配置文件;这个文件不是手动处理的,而是由Redis节点创建和变更的。 +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. + 每一个redis集群节点都需要一个不同的集群配置文件 +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# A Alias for g$lshzxe, so that the "AKE" string means all the events. +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used as +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +########################### ACTIVE DEFRAGMENTATION ####################### +# +# WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested +# even in production and manually tested by multiple engineers for some +# time. +# +# What is active defragmentation? +# ------------------------------- +# +# Active (online) defragmentation allows a Redis server to compact the +# spaces left between small allocations and deallocations of data in memory, +# thus allowing to reclaim back memory. +# +# Fragmentation is a natural process that happens with every allocator (but +# less so with Jemalloc, fortunately) and certain workloads. Normally a server +# restart is needed in order to lower the fragmentation, or at least to flush +# away all the data and create it again. However thanks to this feature +# implemented by Oran Agra for Redis 4.0 this process can happen at runtime +# in an "hot" way, while the server is running. +# +# Basically when the fragmentation is over a certain level (see the +# configuration options below) Redis will start to create new copies of the +# values in contiguous memory regions by exploiting certain specific Jemalloc +# features (in order to understand if an allocation is causing fragmentation +# and to allocate it in a better place), and at the same time, will release the +# old copies of the data. This process, repeated incrementally for all the keys +# will cause the fragmentation to drop back to normal values. +# +# Important things to understand: +# +# 1. This feature is disabled by default, and only works if you compiled Redis +# to use the copy of Jemalloc we ship with the source code of Redis. +# This is the default with Linux builds. +# +# 2. You never need to enable this feature if you don't have fragmentation +# issues. +# +# 3. Once you experience fragmentation, you can enable this feature when +# needed with the command "CONFIG SET activedefrag yes". +# +# The configuration parameters are able to fine tune the behavior of the +# defragmentation process. If you are not sure about what they mean it is +# a good idea to leave the defaults untouched. + +# Enabled active defragmentation +# activedefrag yes + +# Minimum amount of fragmentation waste to start active defrag +# active-defrag-ignore-bytes 100mb + +# Minimum percentage of fragmentation to start active defrag +# active-defrag-threshold-lower 10 + +# Maximum percentage of fragmentation at which we use maximum effort +# active-defrag-threshold-upper 100 + +# Minimal effort for defrag in CPU percentage +# active-defrag-cycle-min 5 + +# Maximal effort for defrag in CPU percentage +# active-defrag-cycle-max 75 + +# Maximum number of set/hash/zset/list fields that will be processed from +# the main dictionary scan +# active-defrag-max-scan-fields 1000 + + +``` \ No newline at end of file diff --git "a/Redis/9-Redis-conf\351\205\215\347\275\256\346\226\207\344\273\266\350\247\243\346\236\220.md" "b/Redis/9-Redis-conf\351\205\215\347\275\256\346\226\207\344\273\266\350\247\243\346\236\220.md" new file mode 100644 index 0000000..d7b2f82 --- /dev/null +++ "b/Redis/9-Redis-conf\351\205\215\347\275\256\346\226\207\344\273\266\350\247\243\346\236\220.md" @@ -0,0 +1,1415 @@ +# Redis配置详解 + +- ```INCLUDES``` :包含一个或多个conf配置文件 +- ```MODULES``` : loadmodule启动时加载指定的模块 +- ```NETWORK``` : 配置端口、pid、连接超时、访问ip等 +- ```GENERAL``` : 是否后台启动、日志配置 +- ```SNAPSHOTTING``` : 转储RDB、bgsave等配置 +- ```REPLICATION``` : 主从复制配置 +- ```SECURITY``` : 安全设置,设置密码访问等 +- ```CLIENTS``` : 客户端连接数设置,maxclients +- ```MEMORY MANAGEMENT``` : 内存管理,maxmemory最大内存;maxmemory-policy 达到最大内存后的内存淘汰处理策略;相关算法有:LRU, LFU and minimal TTL ; +- ```LAZY FREEING``` : 延迟释放空间(延迟删除key等操作) +- ```APPEND ONLY MODE``` : AOF(Append Only File); +- ```LUA SCRIPTING``` : lua脚本配置:Lua脚本的最大执行时间(毫秒) +- ```REDIS CLUSTER``` : Redis Cluster配置:配置文件、超时配置 +- ```CLUSTER DOCKER/NAT support``` +- ```SLOW LOG``` : 慢日志查询 +- ```LATENCY MONITOR``` : 延迟监控 +- ```EVENT NOTIFICATION``` : 事件通知:通知给pub/sub客户端 +- ```ADVANCED CONFIG``` : 高级配置;可以配置hash、跳表节点的大小 +- ```ACTIVE DEFRAGMENTATION``` : 活跃的碎片整理; + + + +#### 指定配置文件启动Redis + +```./redis-server /path/to/redis.conf``` + +#### 内存配置不区分大小写 + +1k、1g、1G + +-------------------------------------------------------------------------- + +```properties +# Redis configuration file example. +# +# Note that in order to read the configuration file, Redis must be +# started with the file path as first argument: +# +# ./redis-server /path/to/redis.conf + +# Note on units: when memory size is needed, it is possible to specify +# it in the usual form of 1k 5GB 4M and so forth: +# +# 1k => 1000 bytes +# 1kb => 1024 bytes +# 1m => 1000000 bytes +# 1mb => 1024*1024 bytes +# 1g => 1000000000 bytes +# 1gb => 1024*1024*1024 bytes +# +# units are case insensitive so 1GB 1Gb 1gB are all the same. + +################################## INCLUDES ################################### + +# Include one or more other config files here. This is useful if you +# have a standard template that goes to all Redis servers but also need +# to customize a few per-server settings. Include files can include +# other files, so use this wisely. +# +# Notice option "include" won't be rewritten by command "CONFIG REWRITE" +# from admin or Redis Sentinel. Since Redis always uses the last processed +# line as value of a configuration directive, you'd better put includes +# at the beginning of this file to avoid overwriting config change at runtime. +# +# If instead you are interested in using includes to override configuration +# options, it is better to use include as the last line. +# +# include /path/to/local.conf +# include /path/to/other.conf + +################################## MODULES ##################################### + +# Load modules at startup. If the server is not able to load modules +# it will abort. It is possible to use multiple loadmodule directives. +# +# loadmodule /path/to/my_module.so +# loadmodule /path/to/other_module.so + +################################## NETWORK ##################################### + +# By default, if no "bind" configuration directive is specified, Redis listens +# for connections from all the network interfaces available on the server. +# It is possible to listen to just one or multiple selected interfaces using +# the "bind" configuration directive, followed by one or more IP addresses. +# +# Examples: +# +# bind 192.168.1.100 10.0.0.1 +# bind 127.0.0.1 ::1 +# +# ~~~ WARNING ~~~ If the computer running Redis is directly exposed to the +# internet, binding to all the interfaces is dangerous and will expose the +# instance to everybody on the internet. So by default we uncomment the +# following bind directive, that will force Redis to listen only into +# the IPv4 loopback interface address (this means Redis will be able to +# accept connections only from clients running into the same computer it +# is running). +# +# IF YOU ARE SURE YOU WANT YOUR INSTANCE TO LISTEN TO ALL THE INTERFACES +# JUST COMMENT THE FOLLOWING LINE. +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +bind 127.0.0.1 + +# Protected mode is a layer of security protection, in order to avoid that +# Redis instances left open on the internet are accessed and exploited. +# +# When protected mode is on and if: +# +# 1) The server is not binding explicitly to a set of addresses using the +# "bind" directive. +# 2) No password is configured. +# +# The server only accepts connections from clients connecting from the +# IPv4 and IPv6 loopback addresses 127.0.0.1 and ::1, and from Unix domain +# sockets. +# +# By default protected mode is enabled. You should disable it only if +# you are sure you want clients from other hosts to connect to Redis +# even if no authentication is configured, nor a specific set of interfaces +# are explicitly listed using the "bind" directive. +protected-mode yes + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 6379 + +# TCP listen() backlog. +# +# In high requests-per-second environments you need an high backlog in order +# to avoid slow clients connections issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +# unixsocket /tmp/redis.sock +# unixsocketperm 700 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# +# If non-zero, use SO_KEEPALIVE to send TCP ACKs to clients in absence +# of communication. This is useful for two reasons: +# +# 1) Detect dead peers. +# 2) Take the connection alive from the point of view of network +# equipment in the middle. +# +# On Linux, the specified value (in seconds) is the period used to send ACKs. +# Note that to close the connection the double of the time is needed. +# On other kernels the period depends on the kernel configuration. +# +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +################################# GENERAL ##################################### + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +daemonize no + +# If you run Redis from upstart or systemd, Redis can interact with your +# supervision tree. Options: +# supervised no - no supervision interaction +# supervised upstart - signal upstart by putting Redis into SIGSTOP mode +# supervised systemd - signal systemd by writing READY=1 to $NOTIFY_SOCKET +# supervised auto - detect upstart or systemd method based on +# UPSTART_JOB or NOTIFY_SOCKET environment variables +# Note: these supervision methods only signal "process is ready." +# They do not enable continuous liveness pings back to your supervisor. +supervised no + +# If a pid file is specified, Redis writes it where specified at startup +# and removes it at exit. +# +# When the server runs non daemonized, no pid file is created if none is +# specified in the configuration. When the server is daemonized, the pid file +# is used even if not specified, defaulting to "/var/run/redis.pid". +# +# Creating a pid file is best effort: if Redis is not able to create it +# nothing bad happens, the server will start and run normally. +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 + +# Specify the log file name. Also the empty string can be used to force +# Redis to log on the standard output. Note that if you use standard +# output for logging but daemonize, logs will be sent to /dev/null +logfile "/tmp/redis6379.log" + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +# syslog-enabled no + +# Specify the syslog identity. +# syslog-ident redis + +# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7. +# syslog-facility local0 + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT where +# dbid is a number between 0 and 'databases'-1 +databases 16 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY. Basically this means +# that normally a logo is displayed only in interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo yes + +################################ SNAPSHOTTING ################################ +# +# Save the DB on disk: +# +# save +# +# Will save the DB if both the given number of seconds and the given +# number of write operations against the DB occurred. +# +# In the example below the behaviour will be to save: +# after 900 sec (15 min) if at least 1 key changed +# after 300 sec (5 min) if at least 10 keys changed +# after 60 sec if at least 10000 keys changed +# +# Note: you can disable saving completely by commenting out all "save" lines. +# +# It is also possible to remove all the previously configured save +# points by adding a save directive with a single empty string argument +# like in the following example: +# +# save "" +# 如果900秒(15分钟)内至少有1个key变更的话 +save 900 1 +# 如果300秒(5分钟)内至少有10个key变更的话 +save 300 10 +# 如果60秒(1分钟)内至少有10000个key变更的话 +save 60 10000 + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# For default that's set to 'yes' as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename dump.rdb + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir ./ + +################################# REPLICATION ################################# + +# Master-Replica replication. Use replicaof to make a Redis instance a copy of +# another Redis server. A few things to understand ASAP about Redis replication. +# +# +------------------+ +---------------+ +# | Master | ---> | Replica | +# | (receive writes) | | (exact copy) | +# +------------------+ +---------------+ +# +# 1) Redis replication is asynchronous, but you can configure a master to +# stop accepting writes if it appears to be not connected with at least +# a given number of replicas. +# 2) Redis replicas are able to perform a partial resynchronization with the +# master if the replication link is lost for a relatively small amount of +# time. You may want to configure the replication backlog size (see the next +# sections of this file) with a sensible value depending on your needs. +# 3) Replication is automatic and does not need user intervention. After a +# network partition replicas automatically try to reconnect to masters +# and resynchronize with them. +# +# replicaof + +# If the master is password protected (using the "requirepass" configuration +# directive below) it is possible to tell the replica to authenticate before +# starting the replication synchronization process, otherwise the master will +# refuse the replica request. +# +# masterauth + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) if replica-serve-stale-data is set to 'no' the replica will reply with +# an error "SYNC with master in progress" to all the kind of commands +# but to INFO, replicaOF, AUTH, PING, SHUTDOWN, REPLCONF, ROLE, CONFIG, +# SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, +# COMMAND, POST, HOST: and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# ------------------------------------------------------- +# WARNING: DISKLESS REPLICATION IS EXPERIMENTAL CURRENTLY +# ------------------------------------------------------- +# +# New replicas and reconnecting replicas that are not able to continue the replication +# process just receiving differences, need to do what is called a "full +# synchronization". An RDB file is transmitted from the master to the replicas. +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child producing +# the RDB file finishes its work. With diskless replication instead once +# the transfer starts, new replicas arriving will be queued and a new transfer +# will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple replicas +# will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync no + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the server +# waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# Replicas send PINGs to server in a predefined interval. It's possible to change +# this interval with the repl_ping_replica_period option. The default value is 10 +# seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# Set the replication backlog size. The backlog is a buffer that accumulates +# replica data when replicas are disconnected for some time, so that when a replica +# wants to reconnect again, often a full resync is not needed, but a partial +# resync is enough, just passing the portion of data the replica missed while +# disconnected. +# +# The bigger the replication backlog, the longer the time the replica can be +# disconnected and later be able to perform a partial resynchronization. +# +# The backlog is only allocated once there is at least a replica connected. +# +# repl-backlog-size 1mb + +# After a master has no longer connected replicas for some time, the backlog +# will be freed. The following option configures the amount of seconds that +# need to elapse, starting from the time the last replica disconnected, for +# the backlog buffer to be freed. +# +# Note that replicas never free the backlog for timeout, since they may be +# promoted to masters later, and should be able to correctly "partially +# resynchronize" with the replicas: hence they should always accumulate backlog. +# +# A value of 0 means to never release the backlog. +# +# repl-backlog-ttl 3600 + +# The replica priority is an integer number published by Redis in the INFO output. +# It is used by Redis Sentinel in order to select a replica to promote into a +# master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel will +# pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# It is possible for a master to stop accepting writes if there are less than +# N replicas connected, having a lag less or equal than M seconds. +# +# The N replicas need to be in "online" state. +# +# The lag in seconds, that must be <= the specified value, is calculated from +# the last ping received from the replica, that is usually sent every second. +# +# This option does not GUARANTEE that N replicas will accept the write, but +# will limit the window of exposure for lost writes in case not enough replicas +# are available, to the specified number of seconds. +# +# For example to require at least 3 replicas with a lag <= 10 seconds use: +# +# min-replicas-to-write 3 +# min-replicas-max-lag 10 +# +# Setting one or the other to 0 disables the feature. +# +# By default min-replicas-to-write is set to 0 (feature disabled) and +# min-replicas-max-lag is set to 10. + +# A Redis master is able to list the address and port of the attached +# replicas in different ways. For example the "INFO replication" section +# offers this information, which is used, among other tools, by +# Redis Sentinel in order to discover replica instances. +# Another place where this info is available is in the output of the +# "ROLE" command of a master. +# +# The listed IP and address normally reported by a replica is obtained +# in the following way: +# +# IP: The address is auto detected by checking the peer address +# of the socket used by the replica to connect with the master. +# +# Port: The port is communicated by the replica during the replication +# handshake, and is normally the port that the replica is using to +# listen for connections. +# +# However when port forwarding or Network Address Translation (NAT) is +# used, the replica may be actually reachable via different IP and port +# pairs. The following two options can be used by a replica in order to +# report to its master a specific set of IP and port, so that both INFO +# and ROLE will report those values. +# +# There is no need to use both the options if you need to override just +# the port or the IP address. +# +# replica-announce-ip 5.5.5.5 +# replica-announce-port 1234 + +################################## SECURITY ################################### + +# Require clients to issue AUTH before processing any other +# commands. This might be useful in environments in which you do not trust +# others with access to the host running redis-server. +# +# This should stay commented out for backward compatibility and because most +# people do not need auth (e.g. they run their own servers). +# +# Warning: since Redis is pretty fast an outside user can try up to +# 150k passwords per second against a good box. This means that you should +# use a very strong password otherwise it will be very easy to break. +# +# requirepass foobared + +# Command renaming. +# +# It is possible to change the name of dangerous commands in a shared +# environment. For instance the CONFIG command may be renamed into something +# hard to guess so that it will still be available for internal-use tools +# but not available for general clients. +# +# Example: +# +# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52 +# +# It is also possible to completely kill a command by renaming it into +# an empty string: +# +# rename-command CONFIG "" +# +# Please note that changing the name of commands that are logged into the +# AOF file or transmitted to replicas may cause problems. + +################################### CLIENTS #################################### + +# Set the max number of connected clients at the same time. By default +# this limit is set to 10000 clients, however if the Redis server is not +# able to configure the process file limit to allow for the specified limit +# the max number of allowed clients is set to the current file limit +# minus 32 (as Redis reserves a few file descriptors for internal uses). +# +# Once the limit is reached Redis will close all the new connections sending +# an error 'max number of clients reached'. +# +# maxclients 10000 + +############################## MEMORY MANAGEMENT ################################ + +# Set a memory usage limit to the specified amount of bytes. +# When the memory limit is reached Redis will try to remove keys +# according to the eviction policy selected (see maxmemory-policy). +# +# If Redis can't remove keys according to the policy, or if the policy is +# set to 'noeviction', Redis will start to reply with errors to commands +# that would use more memory, like SET, LPUSH, and so on, and will continue +# to reply to read-only commands like GET. +# +# This option is usually useful when using Redis as an LRU or LFU cache, or to +# set a hard memory limit for an instance (using the 'noeviction' policy). +# +# WARNING: If you have replicas attached to an instance with maxmemory on, +# the size of the output buffers needed to feed the replicas are subtracted +# from the used memory count, so that network problems / resyncs will +# not trigger a loop where keys are evicted, and in turn the output +# buffer of replicas is full with DELs of keys evicted triggering the deletion +# of more keys, and so forth until the database is completely emptied. +# +# In short... if you have replicas attached it is suggested that you set a lower +# limit for maxmemory so that there is some free RAM on the system for replica +# output buffers (but this is not needed if the policy is 'noeviction'). +# +# maxmemory + +# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory +# is reached. You can select among five behaviors: +# +# volatile-lru -> Evict using approximated LRU among the keys with an expire set. +# allkeys-lru -> Evict any key using approximated LRU. +# volatile-lfu -> Evict using approximated LFU among the keys with an expire set. +# allkeys-lfu -> Evict any key using approximated LFU. +# volatile-random -> Remove a random key among the ones with an expire set. +# allkeys-random -> Remove a random key, any key. +# volatile-ttl -> Remove the key with the nearest expire time (minor TTL) +# noeviction -> Don't evict anything, just return an error on write operations. +# +# LRU means Least Recently Used +# LFU means Least Frequently Used +# +# Both LRU, LFU and volatile-ttl are implemented using approximated +# randomized algorithms. +# +# Note: with any of the above policies, Redis will return an error on write +# operations, when there are no suitable keys for eviction. +# +# At the date of writing these commands are: set setnx setex append +# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd +# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby +# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby +# getset mset msetnx exec sort +# +# The default is: +# +# maxmemory-policy noeviction + +# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated +# algorithms (in order to save memory), so you can tune it for speed or +# accuracy. For default Redis will check five keys and pick the one that was +# used less recently, you can change the sample size using the following +# configuration directive. +# +# The default of 5 produces good enough results. 10 Approximates very closely +# true LRU but costs more CPU. 3 is faster but not very accurate. +# +# maxmemory-samples 5 + +# Starting from Redis 5, by default a replica will ignore its maxmemory setting +# (unless it is promoted to master after a failover or manually). It means +# that the eviction of keys will be just handled by the master, sending the +# DEL commands to the replica as keys evict in the master side. +# +# This behavior ensures that masters and replicas stay consistent, and is usually +# what you want, however if your replica is writable, or you want the replica to have +# a different memory setting, and you are sure all the writes performed to the +# replica are idempotent, then you may change this default (but be sure to understand +# what you are doing). +# +# Note that since the replica by default does not evict, it may end using more +# memory than the one set via maxmemory (there are certain buffers that may +# be larger on the replica, or data structures may sometimes take more memory and so +# forth). So make sure you monitor your replicas and make sure they have enough +# memory to never hit a real out-of-memory condition before the master hits +# the configured maxmemory setting. +# +# replica-ignore-maxmemory yes + +############################# LAZY FREEING #################################### + +# Redis has two primitives to delete keys. One is called DEL and is a blocking +# deletion of the object. It means that the server stops processing new commands +# in order to reclaim all the memory associated with an object in a synchronous +# way. If the key deleted is associated with a small object, the time needed +# in order to execute the DEL command is very small and comparable to most other +# O(1) or O(log_N) commands in Redis. However if the key is associated with an +# aggregated value containing millions of elements, the server can block for +# a long time (even seconds) in order to complete the operation. +# +# For the above reasons Redis also offers non blocking deletion primitives +# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and +# FLUSHDB commands, in order to reclaim memory in background. Those commands +# are executed in constant time. Another thread will incrementally free the +# object in the background as fast as possible. +# +# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled. +# It's up to the design of the application to understand when it is a good +# idea to use one or the other. However the Redis server sometimes has to +# delete keys or flush the whole database as a side effect of other operations. +# Specifically Redis deletes objects independently of a user call in the +# following scenarios: +# +# 1) On eviction, because of the maxmemory and maxmemory policy configurations, +# in order to make room for new data, without going over the specified +# memory limit. +# 2) Because of expire: when a key with an associated time to live (see the +# EXPIRE command) must be deleted from memory. +# 3) Because of a side effect of a command that stores data on a key that may +# already exist. For example the RENAME command may delete the old key +# content when it is replaced with another one. Similarly SUNIONSTORE +# or SORT with STORE option may delete existing keys. The SET command +# itself removes any old content of the specified key in order to replace +# it with the specified string. +# 4) During replication, when a replica performs a full resynchronization with +# its master, the content of the whole database is removed in order to +# load the RDB file just transferred. +# +# In all the above cases the default is to delete objects in a blocking way, +# like if DEL was called. However you can configure each case specifically +# in order to instead release memory in a non-blocking way like if UNLINK +# was called, using the following configuration directives: + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +############################## APPEND ONLY MODE ############################### + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check http://redis.io/topics/persistence for more information. + +appendonly no + +# The name of the append only file (default: "appendonly.aof") + +appendfilename "appendonly.aof" + +# The fsync() call tells the Operating System to actually write data on disk +# instead of waiting for more data in the output buffer. Some OS will really flush +# data on disk, some other OS will just try to do it ASAP. +# +# Redis supports three different modes: +# +# no: don't fsync, just let the OS flush the data when it wants. Faster. +# always: fsync after every write to the append only log. Slow, Safest. +# everysec: fsync only one time every second. Compromise. +# +# The default is "everysec", as that's usually the right compromise between +# speed and data safety. It's up to you to understand if you can relax this to +# "no" that will let the operating system flush the output buffer when +# it wants, for better performances (but if you can live with the idea of +# some data loss consider the default persistence mode that's snapshotting), +# or on the contrary, use "always" that's very slow but a bit safer than +# everysec. +# +# More details please check the following article: +# http://antirez.com/post/redis-persistence-demystified.html +# +# If unsure, use "everysec". + +# appendfsync always +appendfsync everysec +# appendfsync no + +# When the AOF fsync policy is set to always or everysec, and a background +# saving process (a background save or AOF log background rewriting) is +# performing a lot of I/O against the disk, in some Linux configurations +# Redis may block too long on the fsync() call. Note that there is no fix for +# this currently, as even performing fsync in a different thread will block +# our synchronous write(2) call. +# +# In order to mitigate this problem it's possible to use the following option +# that will prevent fsync() from being called in the main process while a +# BGSAVE or BGREWRITEAOF is in progress. +# +# This means that while another child is saving, the durability of Redis is +# the same as "appendfsync none". In practical terms, this means that it is +# possible to lose up to 30 seconds of log in the worst scenario (with the +# default Linux settings). +# +# If you have latency problems turn this to "yes". Otherwise leave it as +# "no" that is the safest pick from the point of view of durability. + +no-appendfsync-on-rewrite no + +# Automatic rewrite of the append only file. +# Redis is able to automatically rewrite the log file implicitly calling +# BGREWRITEAOF when the AOF log size grows by the specified percentage. +# +# This is how it works: Redis remembers the size of the AOF file after the +# latest rewrite (if no rewrite has happened since the restart, the size of +# the AOF at startup is used). +# +# This base size is compared to the current size. If the current size is +# bigger than the specified percentage, the rewrite is triggered. Also +# you need to specify a minimal size for the AOF file to be rewritten, this +# is useful to avoid rewriting the AOF file even if the percentage increase +# is reached but it is still pretty small. +# +# Specify a percentage of zero in order to disable the automatic AOF +# rewrite feature. + +auto-aof-rewrite-percentage 100 +auto-aof-rewrite-min-size 64mb + +# An AOF file may be found to be truncated at the end during the Redis +# startup process, when the AOF data gets loaded back into memory. +# This may happen when the system where Redis is running +# crashes, especially when an ext4 filesystem is mounted without the +# data=ordered option (however this can't happen when Redis itself +# crashes or aborts but the operating system still works correctly). +# +# Redis can either exit with an error when this happens, or load as much +# data as possible (the default now) and start if the AOF file is found +# to be truncated at the end. The following option controls this behavior. +# +# If aof-load-truncated is set to yes, a truncated AOF file is loaded and +# the Redis server starts emitting a log to inform the user of the event. +# Otherwise if the option is set to no, the server aborts with an error +# and refuses to start. When the option is set to no, the user requires +# to fix the AOF file using the "redis-check-aof" utility before to restart +# the server. +# +# Note that if the AOF file will be found to be corrupted in the middle +# the server will still exit with an error. This option only applies when +# Redis will try to read more data from the AOF file but not enough bytes +# will be found. +aof-load-truncated yes + +# When rewriting the AOF file, Redis is able to use an RDB preamble in the +# AOF file for faster rewrites and recoveries. When this option is turned +# on the rewritten AOF file is composed of two different stanzas: +# +# [RDB file][AOF tail] +# +# When loading Redis recognizes that the AOF file starts with the "REDIS" +# string and loads the prefixed RDB file, and continues loading the AOF +# tail. +aof-use-rdb-preamble yes + +################################ LUA SCRIPTING ############################### + +# Max execution time of a Lua script in milliseconds. +# +# If the maximum execution time is reached Redis will log that a script is +# still in execution after the maximum allowed time and will start to +# reply to queries with an error. +# +# When a long running script exceeds the maximum execution time only the +# SCRIPT KILL and SHUTDOWN NOSAVE commands are available. The first can be +# used to stop a script that did not yet called write commands. The second +# is the only way to shut down the server in the case a write command was +# already issued by the script but the user doesn't want to wait for the natural +# termination of the script. +# +# Set it to 0 or a negative value for unlimited execution without warnings. +lua-time-limit 5000 + +################################ REDIS CLUSTER ############################### +# +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# WARNING EXPERIMENTAL: Redis Cluster is considered to be stable code, however +# in order to mark it as "mature" we need to wait for a non trivial percentage +# of users to deploy it in production. +# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +# +# Normal Redis instances can't be part of a Redis Cluster; only nodes that are +# started as cluster nodes can. In order to start a Redis instance as a +# cluster node enable the cluster support uncommenting the following: +# +# cluster-enabled yes + +# Every cluster node has a cluster configuration file. This file is not +# intended to be edited by hand. It is created and updated by Redis nodes. +# Every Redis Cluster node requires a different cluster configuration file. +# Make sure that instances running in the same system do not have +# overlapping cluster configuration file names. +# +# cluster-config-file nodes-6379.conf + +# Cluster node timeout is the amount of milliseconds a node must be unreachable +# for it to be considered in failure state. +# Most other internal time limits are multiple of the node timeout. +# +# cluster-node-timeout 15000 + +# A replica of a failing master will avoid to start a failover if its data +# looks too old. +# +# There is no simple way for a replica to actually have an exact measure of +# its "data age", so the following two checks are performed: +# +# 1) If there are multiple replicas able to failover, they exchange messages +# in order to try to give an advantage to the replica with the best +# replication offset (more data from the master processed). +# Replicas will try to get their rank by offset, and apply to the start +# of the failover a delay proportional to their rank. +# +# 2) Every single replica computes the time of the last interaction with +# its master. This can be the last ping or command received (if the master +# is still in the "connected" state), or the time that elapsed since the +# disconnection with the master (if the replication link is currently down). +# If the last interaction is too old, the replica will not try to failover +# at all. +# +# The point "2" can be tuned by user. Specifically a replica will not perform +# the failover if, since the last interaction with the master, the time +# elapsed is greater than: +# +# (node-timeout * replica-validity-factor) + repl-ping-replica-period +# +# So for example if node-timeout is 30 seconds, and the replica-validity-factor +# is 10, and assuming a default repl-ping-replica-period of 10 seconds, the +# replica will not try to failover if it was not able to talk with the master +# for longer than 310 seconds. +# +# A large replica-validity-factor may allow replicas with too old data to failover +# a master, while a too small value may prevent the cluster from being able to +# elect a replica at all. +# +# For maximum availability, it is possible to set the replica-validity-factor +# to a value of 0, which means, that replicas will always try to failover the +# master regardless of the last time they interacted with the master. +# (However they'll always try to apply a delay proportional to their +# offset rank). +# +# Zero is the only value able to guarantee that when all the partitions heal +# the cluster will always be able to continue. +# +# cluster-replica-validity-factor 10 + +# Cluster replicas are able to migrate to orphaned masters, that are masters +# that are left without working replicas. This improves the cluster ability +# to resist to failures as otherwise an orphaned master can't be failed over +# in case of failure if it has no working replicas. +# +# Replicas migrate to orphaned masters only if there are still at least a +# given number of other working replicas for their old master. This number +# is the "migration barrier". A migration barrier of 1 means that a replica +# will migrate only if there is at least 1 other working replica for its master +# and so forth. It usually reflects the number of replicas you want for every +# master in your cluster. +# +# Default is 1 (replicas migrate only if their masters remain with at least +# one replica). To disable migration just set it to a very large value. +# A value of 0 can be set but is useful only for debugging and dangerous +# in production. +# +# cluster-migration-barrier 1 + +# By default Redis Cluster nodes stop accepting queries if they detect there +# is at least an hash slot uncovered (no available node is serving it). +# This way if the cluster is partially down (for example a range of hash slots +# are no longer covered) all the cluster becomes, eventually, unavailable. +# It automatically returns available as soon as all the slots are covered again. +# +# However sometimes you want the subset of the cluster which is working, +# to continue to accept queries for the part of the key space that is still +# covered. In order to do so, just set the cluster-require-full-coverage +# option to no. +# +# cluster-require-full-coverage yes + +# This option, when set to yes, prevents replicas from trying to failover its +# master during master failures. However the master can still perform a +# manual failover, if forced to do so. +# +# This is useful in different scenarios, especially in the case of multiple +# data center operations, where we want one side to never be promoted if not +# in the case of a total DC failure. +# +# cluster-replica-no-failover no + +# In order to setup your cluster make sure to read the documentation +# available at http://redis.io web site. + +########################## CLUSTER DOCKER/NAT support ######################## + +# In certain deployments, Redis Cluster nodes address discovery fails, because +# addresses are NAT-ted or because ports are forwarded (the typical case is +# Docker and other containers). +# +# In order to make Redis Cluster working in such environments, a static +# configuration where each node knows its public address is needed. The +# following two options are used for this scope, and are: +# +# * cluster-announce-ip +# * cluster-announce-port +# * cluster-announce-bus-port +# +# Each instruct the node about its address, client port, and cluster message +# bus port. The information is then published in the header of the bus packets +# so that other nodes will be able to correctly map the address of the node +# publishing the information. +# +# If the above options are not used, the normal Redis Cluster auto-detection +# will be used instead. +# +# Note that when remapped, the bus port may not be at the fixed offset of +# clients port + 10000, so you can specify any port and bus-port depending +# on how they get remapped. If the bus-port is not set, a fixed offset of +# 10000 will be used as usually. +# +# Example: +# +# cluster-announce-ip 10.1.1.5 +# cluster-announce-port 6379 +# cluster-announce-bus-port 6380 + +################################## SLOW LOG ################################### + +# The Redis Slow Log is a system to log queries that exceeded a specified +# execution time. The execution time does not include the I/O operations +# like talking with the client, sending the reply and so forth, +# but just the time needed to actually execute the command (this is the only +# stage of command execution where the thread is blocked and can not serve +# other requests in the meantime). +# +# You can configure the slow log with two parameters: one tells Redis +# what is the execution time, in microseconds, to exceed in order for the +# command to get logged, and the other parameter is the length of the +# slow log. When a new command is logged the oldest one is removed from the +# queue of logged commands. + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +################################ LATENCY MONITOR ############################## + +# The Redis latency monitoring subsystem samples different operations +# at runtime in order to collect data related to possible sources of +# latency of a Redis instance. +# +# Via the LATENCY command this information is available to the user that can +# print graphs and obtain reports. +# +# The system only logs operations that were performed in a time equal or +# greater than the amount of milliseconds specified via the +# latency-monitor-threshold configuration directive. When its value is set +# to zero, the latency monitor is turned off. +# +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold " if needed. +latency-monitor-threshold 0 + +############################# EVENT NOTIFICATION ############################## + +# Redis can notify Pub/Sub clients about events happening in the key space. +# This feature is documented at http://redis.io/topics/notifications +# +# For instance if keyspace events notification is enabled, and a client +# performs a DEL operation on key "foo" stored in the Database 0, two +# messages will be published via Pub/Sub: +# +# PUBLISH __keyspace@0__:foo del +# PUBLISH __keyevent@0__:del foo +# +# It is possible to select the events that Redis will notify among a set +# of classes. Every class is identified by a single character: +# +# K Keyspace events, published with __keyspace@__ prefix. +# E Keyevent events, published with __keyevent@__ prefix. +# g Generic commands (non-type specific) like DEL, EXPIRE, RENAME, ... +# $ String commands +# l List commands +# s Set commands +# h Hash commands +# z Sorted set commands +# x Expired events (events generated every time a key expires) +# e Evicted events (events generated when a key is evicted for maxmemory) +# A Alias for g$lshzxe, so that the "AKE" string means all the events. +# +# The "notify-keyspace-events" takes as argument a string that is composed +# of zero or multiple characters. The empty string means that notifications +# are disabled. +# +# Example: to enable list and generic events, from the point of view of the +# event name, use: +# +# notify-keyspace-events Elg +# +# Example 2: to get the stream of the expired keys subscribing to channel +# name __keyevent@0__:expired use: +# +# notify-keyspace-events Ex +# +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +############################### ADVANCED CONFIG ############################### + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +hash-max-ziplist-entries 512 +hash-max-ziplist-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +list-max-ziplist-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding in just one case: when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +zset-max-ziplist-entries 128 +zset-max-ziplist-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When an HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entires limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# The limit can be set differently for the three different classes of clients: +# +# normal -> normal clients including MONITOR clients +# replica -> replica clients +# pubsub -> clients subscribed to at least one pubsub channel or pattern +# +# The syntax of every client-output-buffer-limit directive is the following: +# +# client-output-buffer-limit +# +# A client is immediately disconnected once the hard limit is reached, or if +# the soft limit is reached and remains reached for the specified number of +# seconds (continuously). +# So for instance if the hard limit is 32 megabytes and the soft limit is +# 16 megabytes / 10 seconds, the client will get disconnected immediately +# if the size of the output buffers reach 32 megabytes, but will also get +# disconnected if the client reaches 16 megabytes and continuously overcomes +# the limit for 10 seconds. +# +# By default normal clients are not limited because they don't receive data +# without asking (in a push way), but just after a request, so only +# asynchronous clients may create a scenario where data is requested faster +# than it can read. +# +# Instead there is a default limit for pubsub and replica clients, since +# subscribers and replicas receive data in a push fashion. +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Client query buffers accumulate new commands. They are limited to a fixed +# amount by default in order to avoid that a protocol desynchronization (for +# instance due to a bug in the client) will lead to unbound memory usage in +# the query buffer. However you can configure it here if you have very special +# needs, such us huge multi/exec requests or alike. +# +# client-query-buffer-limit 1gb + +# In the Redis protocol, bulk requests, that are, elements representing single +# strings, are normally limited ot 512 mb. However you can change this limit +# here. +# +# proto-max-bulk-len 512mb + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# Normally it is useful to have an HZ value which is proportional to the +# number of clients connected. This is useful in order, for instance, to +# avoid too many clients are processed for each background task invocation +# in order to avoid latency spikes. +# +# Since the default HZ value by default is conservatively set to 10, Redis +# offers, and enables by default, the ability to use an adaptive HZ value +# which will temporary raise when there are many connected clients. +# +# When dynamic HZ is enabled, the actual configured HZ will be used as +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 32 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Redis LFU eviction (see maxmemory setting) can be tuned. However it is a good +# idea to start with the default settings and only change them after investigating +# how to improve the performances and how the keys LFU change over time, which +# is possible to inspect via the OBJECT FREQ command. +# +# There are two tunable parameters in the Redis LFU implementation: the +# counter logarithm factor and the counter decay time. It is important to +# understand what the two parameters mean before changing them. +# +# The LFU counter is just 8 bits per key, it's maximum value is 255, so Redis +# uses a probabilistic increment with logarithmic behavior. Given the value +# of the old counter, when a key is accessed, the counter is incremented in +# this way: +# +# 1. A random number R between 0 and 1 is extracted. +# 2. A probability P is calculated as 1/(old_value*lfu_log_factor+1). +# 3. The counter is incremented only if R < P. +# +# The default lfu-log-factor is 10. This is a table of how the frequency +# counter changes with a different number of accesses with different +# logarithmic factors: +# +# +--------+------------+------------+------------+------------+------------+ +# | factor | 100 hits | 1000 hits | 100K hits | 1M hits | 10M hits | +# +--------+------------+------------+------------+------------+------------+ +# | 0 | 104 | 255 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 1 | 18 | 49 | 255 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 10 | 10 | 18 | 142 | 255 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# | 100 | 8 | 11 | 49 | 143 | 255 | +# +--------+------------+------------+------------+------------+------------+ +# +# NOTE: The above table was obtained by running the following commands: +# +# redis-benchmark -n 1000000 incr foo +# redis-cli object freq foo +# +# NOTE 2: The counter initial value is 5 in order to give new objects a chance +# to accumulate hits. +# +# The counter decay time is the time, in minutes, that must elapse in order +# for the key counter to be divided by two (or decremented if it has a value +# less <= 10). +# +# The default value for the lfu-decay-time is 1. A Special value of 0 means to +# decay the counter every time it happens to be scanned. +# +# lfu-log-factor 10 +# lfu-decay-time 1 + +########################### ACTIVE DEFRAGMENTATION ####################### +# +# WARNING THIS FEATURE IS EXPERIMENTAL. However it was stress tested +# even in production and manually tested by multiple engineers for some +# time. +# +# What is active defragmentation? +# ------------------------------- +# +# Active (online) defragmentation allows a Redis server to compact the +# spaces left between small allocations and deallocations of data in memory, +# thus allowing to reclaim back memory. +# +# Fragmentation is a natural process that happens with every allocator (but +# less so with Jemalloc, fortunately) and certain workloads. Normally a server +# restart is needed in order to lower the fragmentation, or at least to flush +# away all the data and create it again. However thanks to this feature +# implemented by Oran Agra for Redis 4.0 this process can happen at runtime +# in an "hot" way, while the server is running. +# +# Basically when the fragmentation is over a certain level (see the +# configuration options below) Redis will start to create new copies of the +# values in contiguous memory regions by exploiting certain specific Jemalloc +# features (in order to understand if an allocation is causing fragmentation +# and to allocate it in a better place), and at the same time, will release the +# old copies of the data. This process, repeated incrementally for all the keys +# will cause the fragmentation to drop back to normal values. +# +# Important things to understand: +# +# 1. This feature is disabled by default, and only works if you compiled Redis +# to use the copy of Jemalloc we ship with the source code of Redis. +# This is the default with Linux builds. +# +# 2. You never need to enable this feature if you don't have fragmentation +# issues. +# +# 3. Once you experience fragmentation, you can enable this feature when +# needed with the command "CONFIG SET activedefrag yes". +# +# The configuration parameters are able to fine tune the behavior of the +# defragmentation process. If you are not sure about what they mean it is +# a good idea to leave the defaults untouched. + +# Enabled active defragmentation +# activedefrag yes + +# Minimum amount of fragmentation waste to start active defrag +# active-defrag-ignore-bytes 100mb + +# Minimum percentage of fragmentation to start active defrag +# active-defrag-threshold-lower 10 + +# Maximum percentage of fragmentation at which we use maximum effort +# active-defrag-threshold-upper 100 + +# Minimal effort for defrag in CPU percentage +# active-defrag-cycle-min 5 + +# Maximal effort for defrag in CPU percentage +# active-defrag-cycle-max 75 + +# Maximum number of set/hash/zset/list fields that will be processed from +# the main dictionary scan +# active-defrag-max-scan-fields 1000 +``` \ No newline at end of file diff --git "a/Redis/999-Redis\350\277\220\347\273\264\347\263\273\347\273\237\345\221\275\344\273\244.md" "b/Redis/999-Redis\350\277\220\347\273\264\347\263\273\347\273\237\345\221\275\344\273\244.md" new file mode 100644 index 0000000..c2ed8f6 --- /dev/null +++ "b/Redis/999-Redis\350\277\220\347\273\264\347\263\273\347\273\237\345\221\275\344\273\244.md" @@ -0,0 +1,21 @@ +# Redis运维系统命令 + +## 下载解压 +``` +wget http://download.redis.io/releases/redis-5.0.5.tar.gz +tar xzf redis-5.0.5.tar.gz +cd redis-5.0.5 +make +``` + +```shell + tar -zxvf redis-5.0.5.tar.gz +``` + +进入根目录查看: + +```shell +00-RELEASENOTES CONTRIBUTING deps Makefile README.md runtest runtest-moduleapi sentinel.conf tests +BUGS COPYING INSTALL MANIFESTO redis.conf runtest-cluster runtest-sentinel src utils +``` + diff --git a/Redis/pictures/1.jpg b/Redis/pictures/1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e5928a07e6c90a9e0fc74c01b4defddb3a748dd0 GIT binary patch literal 32631 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 bDcs?WrHWuVpLsfCwil6YQ?7_|Gx`4j6Wf0m literal 0 HcmV?d00001 diff --git "a/SpringBoot/99-\350\207\252\345\256\232\344\271\211\345\220\257\345\212\250\345\231\250starter.md" "b/SpringBoot/99-\350\207\252\345\256\232\344\271\211\345\220\257\345\212\250\345\231\250starter.md" index 41eceee..902f95f 100644 --- "a/SpringBoot/99-\350\207\252\345\256\232\344\271\211\345\220\257\345\212\250\345\231\250starter.md" +++ "b/SpringBoot/99-\350\207\252\345\256\232\344\271\211\345\220\257\345\212\250\345\231\250starter.md" @@ -76,13 +76,30 @@ Spring Boot 使用一个注解处理器收集在元数据文件```META-INF/sprin ... } ``` - -- 编写```META-INF/spring-configuration-metadata.json``` 文件 + +- 在```resources/META-INF/spring.factories```中加入这个AutoConfiguration: + - ```properties + org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ + com.spring4all.swagger.SwaggerAutoConfiguration + ``` + +- 添加该starter依赖,并且设置properties: + - ```properties + swagger.url=localhost:11111 + ``` + +在测试类运行时则会加载```swagger.url```属性。 + +## 总结 +自定义springboot的starter,注意这几点: +- 如果自动化配置类需要在程序启动的时候就加载,可以在```META-INF/spring.factories```文件(该文件在SpringBootApplication.run方法执行的时候会加载)中定义。 +- 如果本次加载还需要其他一些lib类的话,可以使用```ConditionalOnClass```注解协助 +- 如果自动化配置类要在使用自定义注解后才加载,可以使用```自定义注解+@Import注解```或```@ImportSelector注解```完成 #### 参考资料 - [SpringBoot自定义启动器](https://docs.spring.io/spring-boot/docs/2.1.5.RELEASE/reference/htmlsingle/#boot-features-custom-starter) - [简单示例](https://www.cnblogs.com/cz-xjw/p/6632402.html) -- [Mybatis-starter](http://www.importnew.com/24164.html) \ No newline at end of file +- [Mybatis-starter案例参考](http://www.importnew.com/24164.html) \ No newline at end of file diff --git "a/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/0-\346\200\273\350\247\210.md" "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/0-\346\200\273\350\247\210.md" new file mode 100644 index 0000000..7132347 --- /dev/null +++ "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/0-\346\200\273\350\247\210.md" @@ -0,0 +1,3 @@ +# 总览 + +**在开发高并发系统时,有三把利器用来保护系统:缓存、降级和限流** \ No newline at end of file diff --git "a/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/2-\346\273\221\345\212\250\347\252\227\345\217\243\347\256\227\346\263\225.md" "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/2-\346\273\221\345\212\250\347\252\227\345\217\243\347\256\227\346\263\225.md" index b9a8838..fbe6386 100644 --- "a/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/2-\346\273\221\345\212\250\347\252\227\345\217\243\347\256\227\346\263\225.md" +++ "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/2-\346\273\221\345\212\250\347\252\227\345\217\243\347\256\227\346\263\225.md" @@ -1,2 +1,8 @@ # 滑动窗口算法 + + +#### 参考资料 + +- [TCP窗口](https://blog.csdn.net/wdscq1234/article/details/52444277) +- [TCP滑动窗口](https://blog.csdn.net/yao5hed/article/details/81046945) \ No newline at end of file diff --git "a/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/3-\344\270\200\350\207\264\346\200\247\345\223\210\345\270\214\347\256\227\346\263\225.md" "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/3-\344\270\200\350\207\264\346\200\247\345\223\210\345\270\214\347\256\227\346\263\225.md" new file mode 100644 index 0000000..5fb71c6 --- /dev/null +++ "b/\345\210\206\345\270\203\345\274\217\351\253\230\345\271\266\345\217\221/3-\344\270\200\350\207\264\346\200\247\345\223\210\345\270\214\347\256\227\346\263\225.md" @@ -0,0 +1,2 @@ +# 一致性哈希算法 + diff --git "a/\351\235\242\350\257\225\346\261\207\346\200\273/1-\351\235\242\350\257\225\345\270\270\351\227\256\351\242\230\347\233\256.md" "b/\351\235\242\350\257\225\346\261\207\346\200\273/1-\351\235\242\350\257\225\345\270\270\351\227\256\351\242\230\347\233\256.md" index 2061b9e..bde2900 100644 --- "a/\351\235\242\350\257\225\346\261\207\346\200\273/1-\351\235\242\350\257\225\345\270\270\351\227\256\351\242\230\347\233\256.md" +++ "b/\351\235\242\350\257\225\346\261\207\346\200\273/1-\351\235\242\350\257\225\345\270\270\351\227\256\351\242\230\347\233\256.md" @@ -26,4 +26,11 @@ - 4.Dubbo - 1.Dubbo是什么? - - 2.Dubbo的SPI机制 \ No newline at end of file + - 2.Dubbo的SPI机制 + + + + +#### 参考资料 + +- [优知学院陈睿](http://youzhixueyuan.com/ali-java-answers-to-four-questions.html) \ No newline at end of file