(转)Redis & EhCache
(二期)6、redis与ehcache综合讲解
https://gitee.com/lv-success/git-second/tree/master/course-6-redis/spring-demo-redis
#解压安装
$ tar xzf redis-2.8.17.tar.gz
$ cd redis-2.8.17
$ make
$ make install
#启动
$ cd src
$ ./redis-server redis.conf
# redis version 2.8.19
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
# 只用最新的,所以可以放到最后。
# include /path/to/local.conf
# include /path/to/other.conf
################################ 通用 #####################################
# 是否后台执行
daemonize yes
# 后台执行的pid文件
# pidfile /var/run/redis.pid
# 0的话,不接受TCP连接
port 6379
# TCP listen() backlog. 虽然listen有两个参数int listen(int s, int backlog); 但是第二个参数会被/proc/sys/net/core/somaxconn覆盖。比如nginx设置的是511,但是也会被这个覆盖成默认的128,
# 所以要/etc/sysctl.conf中添加net.core.somaxconn = 2048 然后 sysctl -p ,就是说,如果软件设置大于linux配置,就是linux配置,软件设置小于linux,就用软件的,就是用最小的那个。
tcp-backlog 511
# 绑定IP请求来源
# bind 192.168.1.100 10.0.0.1
# 在空闲多少秒后关闭链接(0是禁用此功能)
timeout 0
# TCP keepalive
# Linux内核里,下边的值以秒记,相当于tcp_keepalive_time,要用两倍的这个时间才能杀死(画外音,也就是probes*intvl=如下的值了,详见EverNote搜索“linux 在线服务器优化配置”)
# 设成60比较好
tcp-keepalive 0
# 日志记录等级debug》verbose》notice(生产环境)》warning
loglevel notice
# 日志名。空字符串意味着输出到 标准输出。后台运行的redis标准输出是/dev/null。(画外音,所以要设置个文件名)
logfile ""
# 是否把log记到系统日志里。标示是什么?
# syslog-enabled no
# syslog-ident redis
#设置db的数量,默认db是0,你可以用SELECT <dbid> dbid在0到下边的值-1;
databases 16
################################ 快照 ################################
# 保存时间间隔,更新数量。如果1个key更新了,15min保存一次。10个key更新了,5分钟保存一次,10000个key更新了,每1分钟保存一次。主动调用SAVE()会阻塞所有客户端!一般是BGSAVE异步的。
save 900 1
save 300 10
save 60 10000
# 如果最后一次的后台保存RDB snapshot出错,redis就会拒绝所有写请求。这样也相当于一个报警吧。等后台保存继续工作后,redis就允许写了。
# 如果你自己配置好了redis的持久化进程的监控,你可以关闭下边:
stop-writes-on-bgsave-error yes
# 是否压缩dump后的 .rdb 数据库?默认压缩。会省硬盘,但耗CPU。
rdbcompression no
# 是否校验rdb快照?CRC64校验值会放在文件尾部。会导致10%性能下降。关闭后,校验值用0填充
rdbchecksum yes
# DB名称
dbfilename dump.rdb
# 工作目录
# DB会写入这个目录,以上边的名字。“仅追加文件”也会存在这个目录。注意:这里必须是目录名,不能是文件名!
dir ./
################################# 复制集 #################################
# 主从复制。用slaveof去复制另一份redis。
# 1)redis复制是异步的。但你可以让主redis拒绝写请求,当少于某个个数的从redis在线。
# 2)如果复制进程暂停了一小会儿,slave可以进行重新进行部分同步,你可以设置一下复制backlog大小
# 3)是自动的,无需干预。
# slaveof <masterip> <masterport>
# 如果主机需要鉴权,则需要配置密码
# masterauth <master-password>
# 当slave和master断了,会有两种情况:
# 1)默认:slave-serve-stale-data yes 这时,slave接受请求并返回老数据
# 2)如果是no了,则对任何命令都返回SYNC with master in progress,INFO和SLAVEOF命令除外!
slave-serve-stale-data yes
# 2.6之后,redis默认slave都是read-only的,但是slave默认可以执行所有管理员命令。CONFIG,DEBUG等。你可以用rename-command去重命名危险的命令,隐藏他们。
slave-read-only yes
# 复制集同步策略:磁盘或者socket
# 新slave连接或者老slave重新连接时候不能只接收不同,得做一个全同步。需要一个新的RDB文件dump出来,然后从master传到slave。可以有两种情况:
# 1)基于硬盘(disk-backed):master创建一个新进程dump RDB,完事儿之后由父进程(即主进程)增量传给slaves。
# 2)基于socket(diskless):master创建一个新进程直接dump RDB到slave的socket,不经过主进程,不经过硬盘。
# 基于硬盘的话,RDB文件创建后,一旦创建完毕,可以同时服务更多的slave。基于socket的话, 新slave来了后,得排队(如果超出了repl-diskless-sync-delay还没来),完事儿一个再进行下一个。
# 当用diskless的时候,master等待一个repl-diskless-sync-delay的秒数,如果没slave来的话,就直接传,后来的得排队等了。否则就可以一起传。
# disk较慢,并且网络较快的时候,可以用diskless。(默认用disk-based)
repl-diskless-sync no
# 设置成0的话,传输开始ASAP
repl-diskless-sync-delay 5
# Slave发送ping给master。默认10s
# repl-ping-slave-period 10
# 超时时间,包括从master看slave,从slave看master,要大于上边的repl-ping-slave-period
# repl-timeout 60
# SYNC完毕后,在slave的socket里关闭TCP_NODELAY。
# 如果是yes,reids发送少量的TCP包给slave,但可能导致最高40ms的数据延迟。
# 如果是no,那可能在复制的时候,会消耗 少量带宽。
# 默认我们是为了低延迟优化而设置成no,如果主从之间有很多网络跳跃。那设置成yes吧。
repl-disable-tcp-nodelay no
# 复制集后台backlog大小
# 越大,slave可以丢失的时间就越长。
# repl-backlog-size 1mb
# 多久释放backlog,当确认master不再需要slave的时候,多久释放。0是永远不释放。
# repl-backlog-ttl 3600
# 当master不可用,Sentinel会根据slave的优先级选举一个master。最低的优先级的slave,当选master。而配置成0,永远不会被选举。(必须≥0)。默认是100
slave-priority 100
# slave小于几个,网络lag大于几秒的时候,master停止接受write请求。默认对slave数目无限制,给0。网络延迟给10s
# min-slaves-to-write 3
min-slaves-max-lag 10
################################## 安全 ###################################
# 多数情况下无需密码鉴别slave。同时,由于redis处理速度太快,所以爆破速率可达150K/S。10万/S。所以如果你要设置密码,必须设置超强的密码。
# requirepass foobared <--这就是密码
# 命令重命名
# 在一个shared环境里,可以对危险的命令,比如CONFIG,进行重命名:也可以用空字符串,达到完全屏蔽此命令的目的。
# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52
# rename-command CONFIG ""
# 记录进AOF或者传给slave的重命名操作可能会引发问题哦~。
################################### 限制 ####################################
# 设置最大client连接数。默认10000一万个。如果redis没法控制最大文件数。则给到最低32.
# maxclients 10000
# 如果redis用内存超过了设置的限制,第一,开始用maxmemory-policy配置的策略往外删数据,如果配置成了noeviction。所有write都会拒绝,比如set,lpush等。所有读请求可以接受。
# 主要用在把redis用在LRU缓存,或者用在一个内存吃紧又不能删除的策略上。
# 如果你有slave,你应该把最大内存别设置的太大,留一些系统内存给slave output buffers(如果是noeviction策略,就无需这样设置了)
# maxmemory <bytes>
# 内存策略。
# volatile-lru ->用LRU删除设置了ttl的key
# allkeys-lru ->用LRU删除任何key
# volatile-random ->随机删除有ttl的key
# allkeys-random ->随机删除任何key
# volatile-ttl ->删除即将ttl到期的key
# noeviction ->不删,有write的时候报错。
# 如下操作会返回错误
# 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
# 默认是
# maxmemory-policy volatile-lru
# LRU和最小TTL并不是最精确的,但是差不多了也。默认redis每次取3个key然后取最符合删除策略的删除。你可以配置这个数。越低,删除的东西就会越多。比如设置100个,就能删百分之一。
# maxmemory-samples 3
############################## AOF ###############################
# 默认redis异步的dump数据到disk。但如果断电了,那么就会丢失一部分数据了(根据save的配置)。
# AOF提供更好模式。比如用默认的AOF,redis只丢失最近一秒的数据(断电情况),或者最后一个write操作(redis自身错误,os正常)。每个write操作写一次AOF。
# 当AOF文件太大了,redis会自动重写一个aof文件出来。
# AOF和RDB持久化可以同时启用。redis会优先读AOF恢复数据。
# Please check http://redis.io/topics/persistence for more information
appendonly no
# 默认文件名
appendfilename "appendonly.aof"
# fsync()三种:
# no:让OS托管,这样更快。
# always:每次write都刷到log,慢,最安全。
# everysec:每秒一次flush。(默认)
# http://antirez.com/post/redis-persistence-demystified.html
# appendfsync always
appendfsync everysec
# appendfsync no
# 当fsync为always或者everysec,当一个bgsave或者AOF rewrite线程正在耗费大量I/0,redis可能会在fsync上阻塞很久。发生之后就无法fix,即使是另一个线程跑fsync,也会阻塞我们同步的write方法。
# 如下方法可以解决这个问题:当bgsave()或bgrewriteaof()在跑,主进程的fsync()就无法调用。也就是当子进程在save,那段时光相当于redis是appendaof no的。也就是有可能会丢失最多30s的log。
# 所以如果你有lag问题,把下边改成yes,否则就用no。yes意思是暂停aof,拒绝主进程的这次fsync。no是redis是排队的,不会被prevent了,但主进程是阻塞的。
no-appendfsync-on-rewrite no
# 自动重写AOF
# 当AOF文件大小到一定比例,就自动隐式调用BGREWRITEAOF
# 过程:redis记住最后一次rewrite时aof文件大小(重启后没rewrite的话,就是启动时AOF文件的大小),如果现在AOF大小和上次的比例达到特定值就重写。也要指定最小AOF大小,防止到2倍:1M的时候也重写。
# 把percentage改成0,就是禁用重写。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# AOF文件可能在尾部是不完整的(上次system关闭有问题,尤其是mount ext4文件系统时没有加上data=ordered选项。只会发生在os死时,redis自己死不会不完整)。那redis重启时load进内存的时候就有问题了。
# 发生的时候,可以选择redis启动报错,或者load尽量多正常的数据。
# 如果aof-load-truncated是yes,会自动发布一个log给客户端然后load(默认)。如果是no,用户必须手动redis-check-aof修复AOF文件才可以。
aof-load-truncated yes
################################ LUA SCRIPTING ###############################
# 如果达到最大时间限制(毫秒),redis会记个log,然后返回error。
# 当一个脚本超过了最大时限。只有SCRIPT KILL和SHUTDOWN NOSAVE可以用。第一个可以杀没有调write命令的东西。要是已经调用了write,只能用第二个命令杀。
# 设置成0或者负值,时限就无限。
lua-time-limit 5000
################################## SLOW LOG ###################################
# 线程阻塞不能服务其他请求的时间长度。两个参数:第一个是时长(以微秒为单位!,是毫秒的千分之一。)。第二个是log的size,超过了,就会删除之前的log。
# 1000000是一秒。负值是所有请求都记log!下边是0.10S。100毫秒。
slowlog-log-slower-than 10000
# log长度的设置值是没限制。但是需要内存。
slowlog-max-len 128
################################ LATENCY MONITOR ##############################
# 用LATENCY打印redis实例在跑命令时的耗时图表。
# 只记录大于等于下边设置的值的操作。0的话,就是关闭监视。可以动态开启。直接运行CONFIG SET latency-monitor-threshold <milliseconds>
latency-monitor-threshold 0
############################# Event notification ##############################
# 可以通知pub/sub客户端关于key空间的变化。http://redis.io/topics/notifications
# 比如如果开着开关。一个client进行了DEL操作在“foo”key上在database0上。两个消息将会发布通过 pub/sub
# PUBLISH __keyspace@0__:foo del
# PUBLISH __keyevent@0__:del foo
# 大部分人不需要这个功能,并且还需要一定开销,所以默认关闭。
notify-keyspace-events ""
############################### ADVANCED CONFIG ###############################
# hash结构存储,小数据量的用数组,大数据量用map(encoding保存结构信息)
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
# list同上。
list-max-ziplist-entries 512
list-max-ziplist-value 64
# Set在一种情况下会用特殊encoding:整个set是string组成,但是突然需要变成64位带符号整数且是10为根。。不懂。
set-max-intset-entries 512
# zset同set
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
# HyperLogLog 不懂。大于16000完全不可接受!当CPU很顶得住的话,给10000可以。默认给3000.
hll-sparse-max-bytes 3000
# Active rehashing 越多次的操作进入了正在进行rehash的table,越多的rehash步骤需要执行。如果redis是空闲的,那么rehash操作是永远没法停止的,越多的内存也被消耗了。
# 默认就用yes就行 了如果你想释放内存ASAP。
activerehashing yes
# client output buffer限制,可以用来强制关闭传输缓慢的客户端(比如redis pub的东西有比较慢的client无法及时sub)
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds>
# class可以为以下:
#
# normal -> normal clients including MONITOR clients
# slave -> slave clients
# pubsub -> clients subscribed to at least one pubsub channel or pattern
# 当hard限制到了会立即被关闭客户端。如果soft限制到了,会等soft秒。
# 比如硬限制是32m,soft是16m,10secs。到32m就立即断,或者在16m以上停止了10secs。
# 设置成0就是关闭。
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
# redis内部调度(进行关闭timeout的客户端,删除过期key等等)频率,越大则调度频率越高。设置成100以上会对CPU造成大压力除非你对线上实时性要求很高。可以在1~500之间。
hz 10
# 当child进程在rewrite AOF文件,如果这个选项是yes,那么这个file每32MB会写fsync()。这个是保证增量写硬盘而防止写硬盘时I/O突增。
aof-rewrite-incremental-fsync yes
直接自定加载的配置文件即可
主机配置
#演示方便,开放ip连接
bind 0.0.0.0
#后台运行
daemonize yes
#pid文件
pidfile /var/run/redis_6379.pid
#日志文件
logfile "6379.log"
从机配置
bind 0.0.0.0
port 6380
daemonize yes
pidfile /var/run/redis_6380.pid
logfile "6380.log"
#slaveof表示作为从库的配置
slaveof 127.0.0.1 6379
#从库只能读操作
slave-read-only yes
[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6379 info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6380,state=online,offset=1183,lag=0
master_replid:32125185597f85a2155d187ccd57168cf6681395
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1183
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1183
[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6380 info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_repl_offset:1239
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:32125185597f85a2155d187ccd57168cf6681395
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1239
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1239
[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6379 set hello helloworld
OK
[root@izwz95t3hfncu7j54o7zefz src]# ./redis-cli -p 6380 get hello
"helloworld"
创建sentinel.conf配置文件
配置文件说明:
1. port
2. dir
3.sentinel monitor master001 192.168.110.10163792
4.sentinel down-after-milliseconds master001 30000
5.sentinel parallel-syncs master001 1
6.sentinel failover-timeout master001 180000
7.sentinel notification-script <master-name> <script-path>
1. 领导者选举
2. 选出新的master节点
3. 更改slave节点的master节点
4. 通知客户端
5. 客户端连接新的master节点
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir" />
<!-- 默认缓存 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap" />
</defaultCache>
<!-- 测试 -->
<cache name="GoodsType"
eternal="false"
timeToIdleSeconds="2400"
timeToLiveSeconds="2400"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU">
</cache>
</ehcache>