Redis-cluster服务器集群搭建手册

Redis-cluster服务器集群搭建手册


什么redis 4

Redis是什么 4

Redis的优点 4

什么是redis-cluster 4

集群简介 4

安装步骤说明 5

下载 5

编译及安装(如安装过程遇到问题,请查看问题汇总) 5

安装问题汇总 6

配置 7

redis的配置文件结构 7

需要配置的文件 8

使用 9

启动、停止重新加载Redis配置 9

启动Redis服务器 9

停止Redis 9

redis集群的相关运维操作 9

1):添加新master节点 10

2):添加新的slave节点 11

3):在线reshard 数据: 11

4):删除一个slave节点 11

redis操作命令 12

详见http://redisdoc.com/ 12

redis常用命令详解 12

redis-benchmark 12

redis-server 14

redis-cli 15

redis-check-aof 16

redis-check-dump 16

查看、删除key信息 16

获取服务器的信息和统计 16

JAVA连接redis集群 19

使用jedis连接redis集群 20

jedisAPI文档 20

redis-cluster 基本原理 20

Redis 集群数据共享 21

Redis 集群中的主从复制 21

Redis 集群的一致性保证(guarantee) 22

调优 23

设置最大写入内存值 23

内存管理优化 24

Redis配置说明 25

参考文献 41

 

 

什么redis

Redis是什么

REmote DIctionary Server(Redis) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis提供了一些丰富的数据结构,包括 lists, sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当然还包括了对这些数据结构的丰富操作。

Redis的优点

性能极高 – Redis能支持超过 100K+ 每秒的读写频率

丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

原子 – Redis的所有操作都是原子性的,同时Redis还支持对几个操作全并后的原子性执行。

丰富的特性 – Redis还支持 publish/subscribe, 通知, key 过期等等特性。

什么是redis-cluster

集群简介

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施(installation)。

Redis 集群不支持那些需要同时处理多个键的 Redis 命令, 因为执行这些命令需要在多个 Redis 节点之间移动数据, 并且在高负载的情况下, 这些命令将降低 Redis 集群的性能, 并导致不可预测的行为。

Redis 集群通过分区(partition)来提供一定程度的可用性(availability): 即使集群中有一部分节点失效或者无法进行通讯, 集群也可以继续处理命令请求。

Redis 集群提供了以下两个好处:

将数据自动切分(split)到多个节点的能力。

当集群中的一部分节点失效或者无法进行通讯时, 仍然可以继续处理命令请求的能力。

安装步骤说明

下载

下载模板文档:http://pan.baidu.com/s/1sjyXRQX 里面版本不是最新的需要更新请看下面地址

Redis: http://redis.io/download 请下载3.0+的stable版

Ruby: https://www.ruby-lang.org/en/

Rubygems: https://rubygems.org/

Gem:在gems中搜索redis

编译及安装(如安装过程遇到问题,请查看问题汇总)

1、 /opt/redis/

2、 使用cd命令进入到/opt/redis/need/目录,安装目录里的软件。

ruby-2.1.3步骤如下:

       1)、cd ruby-2.1.3

       2)、chmod 755 ./configure

       3)、./configure

       4)、chmod 755 *

       5)、make (此步骤报错的话重新执行上述步骤)

       6)、make install

       Zlib步骤同上:

       Tcl步骤:

       1)、cd tcl8.6.1/unix

       2)-6)、同上

      Rubygems 步骤如下:

      1)、cd rubygems 

      2)、ruby setup.rb

      Redis-3.0.0.gem步骤如下:

      1)、gem install –l redis-3.0.0.gem 

3、 安装redis3.0

      1)、使用cd到/opt/redis/redis-3.0.0-rc1 

      2)、chmod –R 755 *

      3)、make MALLOC=libc

      4)、make install

      5)、cp src/redis-trib.rb /usr/local/bin/

4、修改配置文件

      进入/opt/redis/conf,修改配置文件最大可用内存一项,根据机器配置适量修改

5、 启动所有的redis节点

      1)、Cd /opt/redis

      2)、chmod 755 redis-start

      3)、./redis-start

6、创建redis集群

      1)、cd /opt/redis

      2)、./redis-start

      3)、./cluster-start

安装问题汇总

Q.executable host ruby is required. Use –with-baseruby option

make:*** [id.h] 错误1

A:安装ruby缺少系统ruby centos 运行命令 yum install ruby

 

Q.make:XXXXXXXX 命令未找到

make: ***[parse.c] 错误127

A: yum install XXXX 即可

 

Q: 安装Zlib 之后还是提示缺少Zlib

A: 1.install yum install zlib --此时发现系统安装了zlib

2.进入cd /opt/redis/need/ruby-2.1.3/ext/lib

3.ruby extconf.rb

4.make

5.make install

 

Q: ERROR: While executing gem ... (Gem::Exception)

Unable to require openssl, install OpenSSL and rebuild ruby (preferred) or use non-HTTPS sources

A:1. gem sources --remove http://rubygems.org/

2.gem source -r https://rubygems.org/

3. gem source -a http://ruby.taobao.org/

4.重新运行即可 (外国服务器被墙了,我们用阿里的服务器)

配置

redis的配置文件结构

 使用包含(include)把通用配置和特殊配置分离,方便维护.

 

 

需要配置的文件

1. /opt/redis/redis-start:

此文件包含了你在本机需要启动的redis redis的启动配置(包括端口等)在相关的/conf文件夹下面

2./opt/redis/ cluter-start:

此脚本文件是执行ruby的创建redis集群命令

#redis-trib.rb的create子命令构建

#--replicas 则指定了为Redis Cluster中的每个Master节点配备几个Slave节点

#节点角色由顺序决定,先master之后是slave(为方便辨认,slave的端口比master大1000)

redis-trib.rb create --replicas 1 10.10.34.14:6380 10.10.34.14:6381 10.10.34.14:6382 10.10.34.14:7380 10.10.34.14:7381 10.10.34.14:7382

3./opt/redis/ redis-common.conf:

redis的配置和优化都是在这里面,我帮你注释好了,你只需要打开思考自己需要的配置改动参数菊科

4./opt/redis/conf/*:

每一个单独节点的一些策略和端口监听

 

 

使用

启动、停止重新加载Redis配置

进入<REDIS_HOME>的bin目录下。

启动Redis服务器

redis操作命令: http://redisdoc.com/

命令:./redis-star

./cluter-start

测试启动 redis-cli ping 返回PONG,启动成功,此命令测试是否已经启动。

查看端口是否被占用:netstat -ntlp |grep 6379  

查看redis 进程 ps –er | grep redis

停止Redis

关闭服务

redis-cli shutdown

如果非默认端口,可指定端口:

redis-cli -p 6380 shutdown

redis服务关闭后,缓存数据会自动dump到硬盘上,硬盘地址为redis.conf中的配置项dbfilename dump.rdb所设定 

强制备份数据到磁盘,使用如下命令  

    redis-cli save 或者 redis-cli -p 6380 save(指定端口)

redis集群的相关运维操作

1):添加新master节点

(1)添加一个master节点:创建一个空节点(empty node),然后将某些slot移动到这个空节点上,这个过程目前需要人工干预

a):根据端口生成配置文件(ps:establish_config.sh是我自己写的输出配置脚本)

sh establish_config.sh 6386 > conf/redis-6386.conf  

b):启动节点

redis-server /opt/redis/conf/redis-6386.conf > /opt/redis/logs/redis-6386.log 2>&1 &  

c):加入空节点到集群

add-node  将一个节点添加到集群里面, 第一个是新节点ip:port, 第二个是任意一个已存在节点ip:port

redis-trib.rb add-node 10.10.34.14:6386 10.10.34.14:6381  

node:新节点没有包含任何数据, 因为它没有包含任何slot。新加入的加点是一个主节点, 当集群需要将某个从节点升级为新的主节点时, 这个新节点不会被选中

d):为新节点分配slot

redis-trib.rb reshard 10.10.34.14:6386  

#根据提示选择要迁移的slot数量(ps:这里选择500)  

How many slots do you want to move (from 1 to 16384)? 500  

#选择要接受这些slot的node-id  

What is the receiving node ID? f51e26b5d5ff74f85341f06f28f125b7254e61bf  

#选择slot来源:  

#all表示从所有的master重新分配,  

#或者数据要提取slot的master节点id,最后用done结束  

Please enter all the source node IDs.  

  Type 'all' to use all the nodes as source nodes for the hash slots.  

  Type 'done' once you entered all the source nodes IDs.  

Source node #1:all  

#打印被移动的slot后,输入yes开始移动slot以及对应的数据.  

#Do you want to proceed with the proposed reshard plan (yes/no)? yes  

#结束  

2):添加新的slave节点

a):前三步操作同添加master一样

b)第四步:redis-cli连接上新节点shell,输入命令:cluster replicate 对应master的node-id

cluster replicate 2b9ebcbd627ff0fd7a7bbcc5332fb09e72788835  

note:在线添加slave 时,需要dump整个master进程,并传递到slave,再由 slave加载rdb文件到内存,rdb传输过程中Master可能无法提供服务,整个过程消耗大量io,小心操作.

例如本次添加slave操作产生的rdb文件

-rw-r--r-- 1 root root  34946 Apr 17 18:23 dump-6386.rdb  

-rw-r--r-- 1 root root  34946 Apr 17 18:23 dump-7386.rdb  

3):在线reshard 数据:

对于负载/数据不均匀的情况,可以在线reshard slot来解决,方法与添加新master的reshard一样,只是需要reshard的master节点是老节点.

4):删除一个slave节点

Java代码  

#redis-trib del-node ip:port '<node-id>'  

redis-trib.rb del-node 10.10.34.14:7386 'c7ee2fca17cb79fe3c9822ced1d4f6c5e169e378'  

6):删除一个master节点

  a):删除master节点之前首先要使用reshard移除master的全部slot,然后再删除当前节点(目前只能把被删除

master的slot迁移到一个节点上)

 

#把10.10.34.14:6386当前master迁移到10.10.34.14:6380上  

redis-trib.rb reshard 10.10.34.14:6380  

#根据提示选择要迁移的slot数量(ps:这里选择500)  

How many slots do you want to move (from 1 to 16384)? 500(被删除master的所有slot数量)  

#选择要接受这些slot的node-id(10.10.34.14:6380)  

What is the receiving node ID? c4a31c852f81686f6ed8bcd6d1b13accdc947fd2 (ps:10.10.34.14:6380的node-id)  

Please enter all the source node IDs.  

  Type 'all' to use all the nodes as source nodes for the hash slots.  

  Type 'done' once you entered all the source nodes IDs.  

Source node #1:f51e26b5d5ff74f85341f06f28f125b7254e61bf(被删除master的node-id)  

Source node #2:done  

#打印被移动的slot后,输入yes开始移动slot以及对应的数据.  

#Do you want to proceed with the proposed reshard plan (yes/no)? yes  

b):删除空master节点

redis-trib.rb del-node 10.10.34.14:6386 'f51e26b5d5ff74f85341f06f28f125b7254e61bf'  

 

redis操作命令

详见http://redisdoc.com/

redis常用命令详解

redis-benchmark

Redis性能测试工具,测试Redis在你的系统及你的配置下的读写性能。

redis的基准信息和性能检测。

redis-benchmark -h localhost -p 6379 -c 100 -n 100000

100个并发连接,100000个请求,检测host为localhost 端口为6379的redis服务器性能

./redis-benchmark -n 100000 –c 50

    ====== –c 50 ======

    100000 requests completed in 1.93 seconds (100000个请求完成于 1.93 秒 )

    50 parallel clients (每个请求有50个并发客户端)

    3 bytes payload (每次写入3字节)

    keep alive: 1 (保持1个连接)

    58.50% <= 0 milliseconds

    99.17% <= 1 milliseconds

    99.58% <= 2 milliseconds

    99.85% <= 3 milliseconds

    99.90% <= 6 milliseconds

    100.00% <= 9 milliseconds

(所有请求在62毫秒内完成)

    114293.71 requests per second(每秒 114293.71 次查询)

   

redis-benchmark参数

-h

设置检测主机IP地址,默认为127.0.0.1

-p

设置检测主机的端口号,默认为6379

-s<socket>

服务器套接字(压倒主机和端口)

-c

并发连接数

-n

请求数

-d

测试使用的数据集的大小/字节的值(默认3字节)

-k

1:表示保持连接(默认值)0:重新连接

-r

SET/GET/INCR方法使用随机数插入数值,设置10则插入值为rand:000000000000 - rand:000000000009

-P

默认为1(无管道),当网络延迟过长时,使用管道方式通信(请求和响应打包发送接收)

-q

简约信息模式,只显示查询和秒值等基本信息。

--csv

以CSV格式输出信息

-l

无线循环插入测试数据,ctrl+c停止

-t<tests>

只运行<tests>测试逗号分隔的列表命令,如:-t ping,set,get

-I

空闲模式。立即打开50个空闲连接和等待。

例子:

$ redis-benchmark基本测试

$ redis-benchmark -h 192.168.1.1 -p 6379 -n 100000 -c 20

$ redis-benchmark -t set -n 1000000 -r 100000000

$ redis-benchmark -t ping,set,get -n 100000 –csv

$ redis-benchmark -r 10000 -n 10000 lpush mylist ele:rand:000000000000

 

 

redis-server

Redis服务器的daemon启动程序

redis-server 启动并加装默认配置文件[/path/to/redis.conf]

redis-server /biran/conf/redis.conf 启动并加装指定配置文件

redis-server - (read config from stdin) 使用标准输入读取配置为启动参数

redis-server --test-memory 256 检测256MB内存

redis-server –version 查版本号

redis-cli

Redis命令行操作工具。当然,你也可以用telnet根据其纯文本协议来操作

可输入redis-cli直接进入命令行操作界面。

   

redis-cli参数

-h

设置检测主机IP地址,默认为127.0.0.1

-p

设置检测主机的端口号,默认为6379

-s<socket>

服务器套接字(压倒主机和端口)

-a

连接到Master服务器时使用的密码

-r

执行指定的N次命令

-i

执行命令后等待N秒,如–i 0.1 info(执行后等0.1秒)

-n

指定连接N号ID数据库,如 –n 3(连接3号数据库)

-x

从控制台输入的信息中读取最后一个参数

-d

定义多个定界符为默认输出格式(默认: \n)

--raw

使用原数据格式返回输出内容

--latency

进入一个不断延时采样的特殊模式

--slave

模拟一个从服务器到主服务器的命令显示反馈

--pipe

使用管道协议模式

--bigkeys

监听显示数据量大的key值,--bigkeys -i 0.1

--help

显示命令行帮助信息

--version

显示版本号

例子:

$ redis-cli进入命令行模式

$ redis-cli -r 3 info 重复执行info命令三次

$ cat testStr.txt | redis-cli -x set testStr读取testStr.txt文件所有内容设置为testStr的值

$ redis-cli -r 100 lpush mylist x

$ redis-cli -r 100 -i 1 info | grep used_memory_human

 

 

redis-check-aof

更新日志检查 ,加--fix参数为修复log文件

redis-check-aof appendonly.aof

 

redis-check-dump

检查本地数据库文件

redis-check-dump dump.rdb

 

查看、删除key信息

redis-cli keys \*   #查看所有键值信息

redis-cli -n 1 keys "test*" | xargs redis-cli -n 1 del 删除DBID为1的test开头的key值

获取服务器的信息和统计

redis-cli info查询系统信息。默认为localhost,端口为6379。

redis-cli -p 6379 info | grep '\<used_memory\>' 过滤查询used_memory属性

当used_memory_rss接近maxmemory或者used_memory_peak超过maxmemory时,要加大maxmemory 负责性能下降

redis服务的统计信息:

   

redis_version:2.4.14

Redis版本号

redis_git_sha1:00000000

 

redis_git_dirty:0

Git版本??

arch_bits:64

64位系统

multiplexing_api:epoll

 

gcc_version:4.1.2

gcc版本号

process_id:5551

当前服务器进程id

uptime_in_seconds:1538

正常工作时间(秒)

uptime_in_days:0

正常工作天数

lru_clock:1975799

 

used_cpu_sys:0.04

Cpu使用率

used_cpu_user:0.09

 

used_cpu_sys_children:0.01

 

used_cpu_user_children:0.04

 

connected_clients:2

客户端连接数

connected_slaves:0

从服务器连接数

client_longest_output_list:0

 

client_biggest_input_buf:0

 

blocked_clients:0

锁定的客户端

used_memory:3765272

redis数据占用的内存,单位bytes(字节)

used_memory_human:3.59M

重点关注!

used_memory_rss:4665344

redis占用的物理内存

used_memory_peak:3756712

redis使用物理内存的峰值

used_memory_peak_human:3.58M

 

mem_fragmentation_ratio:1.24

内存碎片率

mem_allocator:jemalloc-2.2.5

内存分配器版本

loading:0

 

aof_enabled:0

是否开启纯累加模式

changes_since_last_save:0

 

bgsave_in_progress:0

后台异步保存数据的进程数

last_save_time:1340962658

 

bgrewriteaof_in_progress:0

异步重写 AOF 文件以反应当前数据库的状态的进程数

total_connections_received:3

接受到的总连接数

total_commands_processed:10156

服务器处理的命令数量

expired_keys:0

失效key的总数量

evicted_keys:0

已删除的key的总数量

keyspace_hits:0

Key命中次数

keyspace_misses:0

Key未命中次数

pubsub_channels:0

订阅信息

pubsub_patterns:0

 

latest_fork_usec:579

最近子进程

vm_enabled:0

是否使用虚拟内存0:不使用,1:使用

role:slave

master为主服务器slave为从服务器

master_host:127.0.0.1

连接主服务器IP

master_port:6379

连接主服务器端口号

master_link_status:up

 

master_last_io_seconds_ago:2

距离最后一次的连接时间

master_sync_in_progress:0

同步主服务器进程数

db0:keys=3,expires=0

1号数据库保存的key数量,及超时时间

db1:keys=1,expires=0

2号数据库保存的key数量,及超时时间

 

 

JAVA连接redis集群

 

使用jedis连接redis集群

在pom文件中加入关联

<dependency>

<groupId>redis.clients</groupId>

<artifactId>jedis</artifactId>

<version>2.7.2</version>

</dependency>

JAVA代码:

Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();

//Jedis Cluster will attempt to discover cluster nodes automatically

jedisClusterNodes.add(new HostAndPort("192.168.80.104", 6379));

jedisClusterNodes.add(new HostAndPort("192.168.80.104", 6381));

jedisClusterNodes.add(new HostAndPort("192.168.80.104", 7379));

JedisCluster jc = new JedisCluster(jedisClusterNodes);

jc.set("xym01", "bar");

String value = jc.get("xym01");

System.out.println(value);

jedisAPI文档

更多信息请查看官方API说明:

http://tool.oschina.net/apidocs/apidoc?api=jedis-2.1.0

 

 

redis-cluster 基本原理

Redis 集群数据共享

Redis 集群使用数据分片(sharding)而非一致性哈希(consistency hashing)来实现: 一个 Redis 集群包含 16384 个哈希槽(hash slot), 数据库中的每个键都属于这 16384 个哈希槽的其中一个, 集群使用公式 CRC16(key) % 16384 来计算键 key 属于哪个槽, 其中CRC16(key) 语句用于计算键 key 的 CRC16 校验和 

集群中的每个节点负责处理一部分哈希槽。 举个例子, 一个集群可以有三个哈希槽, 其中:

节点 A 负责处理 0 号至 5500 号哈希槽。

节点 B 负责处理 5501 号至 11000 号哈希槽。

节点 C 负责处理 11001 号至 16384 号哈希槽。

这种将哈希槽分布到不同节点的做法使得用户可以很容易地向集群中添加或者删除节点。 比如说:

如果用户将新节点 D 添加到集群中, 那么集群只需要将节点 A 、B 、 C 中的某些槽移动到节点 D 就可以了。

 与此类似, 如果用户要从集群中移除节点 A , 那么集群只需要将节点 A 中的所有哈希槽移动到节点 B 和节点 C , 然后再移除空白(不包含任何哈希槽)的节点 A 就可以了。

因为将一个哈希槽从一个节点移动到另一个节点不会造成节点阻塞, 所以无论是添加新节点还是移除已存在节点, 又或者改变某个节点包含的哈希槽数量, 都不会造成集群下线。

Redis 集群中的主从复制

为了使得集群在一部分节点下线或者无法与集群的大多数(majority)节点进行通讯的情况下, 仍然可以正常运作, Redis 集群对节点使用了主从复制功能: 集群中的每个节点都有 1 个至 N 个复制品(replica), 其中一个复制品为主节点(master), 而其余的 N-1 个复制品为从节点(slave)。

在之前列举的节点 A 、B 、C 的例子中, 如果节点 B 下线了, 那么集群将无法正常运行, 因为集群找不到节点来处理 5501 号至 11000号的哈希槽。

另一方面, 假如在创建集群的时候(或者至少在节点 B 下线之前), 我们为主节点 B 添加了从节点 B1 , 那么当主节点 B 下线的时候, 集群就会将 B1 设置为新的主节点, 并让它代替下线的主节点 B , 继续处理 5501 号至 11000 号的哈希槽, 这样集群就不会因为主节点 B 的下线而无法正常运作了。

不过如果节点 B 和 B1 都下线的话, Redis 集群还是会停止运作。

Redis 集群的一致性保证(guarantee)

Redis 集群不保证数据的强一致性(strong consistency): 在特定条件下, Redis 集群可能会丢失已经被执行过的写命令。

使用异步复制(asynchronous replication)是 Redis 集群可能会丢失写命令的其中一个原因。 考虑以下这个写命令的例子:

 客户端向主节点 B 发送一条写命令。

 主节点 B 执行写命令,并向客户端返回命令回复。

 主节点 B 将刚刚执行的写命令复制给它的从节点 B1 、 B2 和 B3 。

如你所见, 主节点对命令的复制工作发生在返回命令回复之后, 因为如果每次处理命令请求都需要等待复制操作完成的话, 那么主节点处理命令请求的速度将极大地降低 —— 我们必须在性能和一致性之间做出权衡。

如果真的有必要的话, Redis 集群可能会在将来提供同步地(synchronou)执行写命令的方法。

Redis 集群另外一种可能会丢失命令的情况是, 集群出现网络分裂(network partition), 并且一个客户端与至少包括一个主节点在内的少数(minority)实例被孤立。

举个例子, 假设集群包含 A 、 B 、 C 、 A1 、 B1 、 C1 六个节点, 其中 A 、B 、C 为主节点, 而 A1 、B1 、C1 分别为三个主节点的从节点, 另外还有一个客户端 Z1 。

假设集群中发生网络分裂, 那么集群可能会分裂为两方, 大多数(majority)的一方包含节点 A 、C 、A1 、B1 和 C1 , 而少数(minority)的一方则包含节点 B 和客户端 Z1 。

在网络分裂期间, 主节点 B 仍然会接受 Z1 发送的写命令:

如果网络分裂出现的时间很短, 那么集群会继续正常运行;

但是, 如果网络分裂出现的时间足够长, 使得大多数一方将从节点 B1 设置为新的主节点, 并使用 B1 来代替原来的主节点 B , 那么 Z1 发送给主节点 B 的写命令将丢失。

注意, 在网络分裂出现期间, 客户端 Z1 可以向主节点 B 发送写命令的最大时间是有限制的, 这一时间限制称为节点超时时间(node timeout), 是 Redis 集群的一个重要的配置选项:

对于大多数一方来说, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么集群会将这个主节点视为下线, 并使用从节点来代替这个主节点继续工作。

对于少数一方, 如果一个主节点未能在节点超时时间所设定的时限内重新联系上集群, 那么它将停止处理写命令, 并向客户端报告错误。

调优

设置最大写入内存值

Redis当使用了多少物理内存后就开始拒绝后续的写入请求,该参数能很好的保护好你的Redis不会因为使用了过多的物理内存而导致swap,最终严重s

 

 

454行:预估设置redis需要最大内存8G,

 

 

内存管理优化

Redis Hash是value内部为一个HashMap,如果该Map的成员数比较少,则会采用类似一维线性的紧凑格式来存储该Map, 即省去了大量指针的内存开销,这个参数控制对应在redis.conf配置文件中下面2项:

hash-max-zipmap-entries 64 hash-max-zipmap-value 512

        当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap。

        hash-max-zipmap-value 含义是当 value这个Map内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。

        以上2个条件任意一个条件超过设置值都会转换成真正的HashMap,也就不会再节省内存了,那么这个值是不是设置的越大越好呢,答案当然是否定的,HashMap的优势就是查找和操作的时间复杂度都是O(1)的,而放弃Hash采用一维存储则是O(n)的时间复杂度,如果

成员数量很少,则影响不大,否则会严重影响性能,所以要权衡好这个值的设置,总体上还是最根本的时间成本和空间成本上的权衡。

 

list-max-ziplist-value 64 list-max-ziplist-entries 512

        list数据类型节点值大小小于多少字节会采用紧凑存储格式、list数据类型多少节点以下会采用去指针的紧凑存储格式。d

Redis配置说明

# Redis示例配置文件

 

# 注意单位问题:当需要设置内存大小的时候,可以使用类似1k、5GB、4M这样的常见格式:

# 1k => 1000 bytes

# 1kb => 1024 bytes

# 1m => 1000000 bytes

# 1mb => 1024*1024 bytes

# 1g => 1000000000 bytes

# 1gb => 1024*1024*1024 bytes

# 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其内存单位转换方式如下(不区分大小写,比如 1gb 1Gb 1GB 1gB均可)

 

########## 基本配置 ##########

 

# 默认情况下,redis不是在后台模式运行的,如果需要在后台进程运行,把该项的值更改为yes,默认为no

daemonize no

 

# 如redis服务以后台进程运行的时候,Redis默认会把pid写入/var/run/redis.pid文件组,你可以配置到其他文件路径。

# 当运行多个redis服务时,需要指定不同的pid文件和端口

pidfile /var/run/redis.pid

 

# 指定redis监听端口,默认为6379

# 如果端口设置为0,Redis就不会监听TCP套接字。

port 6379

 

# 指定redis只接收来自于该IP地址的请求,如果不进行设置,默认将处理所有请求,

# 在生产环境中最好设置该项

# bind 127.0.0.1

 

# 指定用来监听连接的unxi套接字的路径。这个没有默认值,所以如果不指定的话,Redis就不会通过unix套接字来监听。

# unixsocket /tmp/redis.sock

# unixsocketperm 755

 

# 设置客户端连接时的超时时间,单位为秒。当客户端在这段时间内没有发出任何指令,那么关闭该连接

# 默认值:0代表禁用,永不关闭

timeout 0

 

# 指定日志记录级别

# Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose

# debug 记录很多信息,用于开发和测试

# varbose 很多精简的有用信息,不像debug会记录那么多

# notice 普通的verbose,常用于生产环境

# warning 只有非常重要或者严重的信息会记录到日志

loglevel verbose

 

# 配置log文件名称和全路径地址

# 默认值为stdout,使用“标准输出”,默认后台模式会输出到/dev/null

logfile stdout

 

# 要使用linux系统日志记录器很简单,只要设置"syslog-enabled=yes",并且需要设置其他syslog参数,默认是no

# syslog-enabled no

 

# 指定linux系统日志syslog的标示符,若是"syslog-enabled=no",则这个选项无效。

# syslog-ident redis

 

# 指定linux系统日志syslog 设备(facility), 必须是USER或者LOCAL0到LOCAL7之间

# syslog-facility local0

 

# 可用数据库数,默认值为16,默认数据库存储在DB 0号ID库中,无特殊需求,建议仅设置一个数据库 databases 1

# 查询数据库使用 SELECT <dbid>

# dbid介于 0 到 'databases'-1 之间

databases 16

 

########## SNAPSHOTTING 快照 ##########

#

# 把数据库存到磁盘上:

#

# save <seconds> <changes>

#

# 会在指定秒数和数据变化次数之后把数据库写到磁盘上。

#

# 下面的例子将会进行把数据写入磁盘的操作:

# 900秒(15分钟)之后,且至少有1个key(次)变更

# 300秒(5分钟)之后,且至少有10个key(次)变更

# 60秒之后,且至少有10000个key(次)变更

#

# 注意:如果不需要写磁盘,则把所有 "save" 设置注释掉,即实现全内存服务器。

 

save 900 1

save 300 10

save 60 10000

 

# 当导出到 .rdb 数据库时是否用LZF压缩字符串对象。

# 默认设置为 "yes",

# 如果想节省CPU的话,可以把这个设置为 "no",但是如果有可以压缩的key却没有压缩的话,那数据文件就会变得更大

rdbcompression yes

 

# 数据库的文件名及存放路径

dbfilename dump.rdb

 

# 工作目录

# 本地数据库会写到这个目录下,文件名就是上面的 "dbfilename" 的值。

# 累加文件也放这里。

# 注意你这里指定的必须是目录,不是文件名。

dir ./

 

########## REPLICATION 同步 ##########

#

# 主从同步。通过 slaveof 配置来实现Redis实例的备份。

# 注意,这里是本地从远端复制数据。也就是说,本地可以有不同的数据库文件、绑定不同的IP、监听不同的端口。

# 当本机为从服务时,设置主服务的IP及端口,在Redis启动时,它会自动从主服务进行数据同步

# slaveof <masterip> <masterport>

 

# 如果主服务master设置了密码(通过下面的 "requirepass" 选项来配置),slave服务连接master的密码,那么slave在开始同步之前必须进行身份验证,否则它的同步请求会被拒绝。

#当本机为从服务时,设置主服务的连接密码

# masterauth <master-password>

 

# 当一个slave失去和master的连接,或者同步正在进行中,slave的行为有两种可能:

# 1) 如果 slave-serve-stale-data 设置为 "yes" (默认值),slave会继续响应客户端请求,可能是正常数据,也可能是还没获得值的空数据。

# 2) 如果 slave-serve-stale-data 设置为 "no",slave会回复"正在从master同步(SYNC with master in progress)"来处理各种请求,除了 INFO 和 SLAVEOF 命令。

slave-serve-stale-data yes

 

# slave根据指定的时间间隔向服务器发送ping请求。

# 时间间隔可以通过 repl_ping_slave_period 来设置。

# 默认10秒

# repl-ping-slave-period 10

 

# 下面的选项设置了大块数据I/O、向master请求数据和ping响应的过期时间。

# 默认值60秒。

# 一个很重要的事情是:确保这个值比 repl-ping-slave-period 大,否则master和slave之间的传输过期时间比预想的要短。

# repl-timeout 60

 

########## SECURITY 安全 ##########

 

# 要求客户端在处理任何命令时都要验证身份和设置密码。

# 如果你不相信请求者,这个功能很有用。

# 为了向后兼容的话,这段应该注释掉。而且大多数人不需要身份验证(例如:它们运行在自己的服务器上。)

# 警告:外部使用者可以每秒尝试150k的密码来试图破解密码,这意味着你需要一个高强度的密码,否则破解太容易了。

# 设置连接密码

# requirepass foobared

 

# 命令重命名,可设置多个

# 在共享环境下,可以为危险命令改变名字。比如,你可以为 CONFIG 改个其他不太容易猜到的名字,这样你自己仍然可以使用,而别人却没法知道它。

# 例如:

# rename-command CONFIG b840fc02d524045429941cc15f59e41cb7be6c52

# rename-command info info_biran

# rename-command set set_biran

# 甚至也可以通过给命令赋值一个空字符串来完全禁用这条命令:

# rename-command CONFIG ""

 

########## LIMITS 限制 ##########

 

# 设置最大同时连接客户端数量。

# 默认没有限制,这个关系到Redis进程能够打开的文件描述符数量。

# 特殊值"0"表示没有限制。

# 一旦达到这个限制,Redis会关闭所有新连接并发送错误"达到最大用户数上限(max number of clients reached)"

# maxclients 128

 

# 不要用比设置的上限更多的内存。一旦内存使用达到上限,Redis会根据选定的回收策略(参见:maxmemmory-policy:内存策略设置)删除key。

# 如果因为删除策略问题Redis无法删除key,或者策略设置为 "noeviction",Redis会回复需要更多内存的错误信息给命令。

# 例如,SET,LPUSH等等。但是会继续合理响应只读命令,比如:GET。

# 在使用Redis作为LRU缓存,或者为实例设置了硬性内存限制的时候(使用 "noeviction" 策略)的时候,这个选项还是满有用的。

# 警告:当一堆slave连上达到内存上限的实例的时候,响应slave需要的输出缓存所需内存不计算在使用内存当中。

# 这样当请求一个删除掉的key的时候就不会触发网络问题/重新同步的事件,然后slave就会收到一堆删除指令,直到数据库空了为止。

# 简而言之,如果你有slave连上一个master的话,那建议你把master内存限制设小点儿,确保有足够的系统内存用作输出缓存。

# (如果策略设置为"noeviction"的话就不无所谓了)

# 设置最大内存,达到最大内存设置后,Redis会先尝试清除已到期或即将到期的Key,当此方法处理后,任到达最大内存设置,将无法再进行写入操作。

# maxmemory 256000000分配256M内存

# maxmemory <bytes>

 

# 内存策略:如果达到内存限制了,Redis如何删除key。你可以在下面五个策略里面选:

#

# volatile-lru -> 根据LRU算法生成的过期时间来删除。

# allkeys-lru -> 根据LRU算法删除任何key。

# volatile-random -> 根据过期设置来随机删除key。

# allkeys->random -> 无差别随机删。

# volatile-ttl -> 根据最近过期时间来删除(辅以TTL)

# noeviction -> 谁也不删,直接在写操作时返回错误。

#

# 注意:对所有策略来说,如果Redis找不到合适的可以删除的key都会在写操作时返回一个错误。

#

# 这里涉及的命令: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会检查三个key然后取最旧的那个,你可以通过下面的配置项来设置样本的个数。

# maxmemory-samples 3

 

########## APPEND ONLY MODE 纯累加模式 ##########

 

# 默认情况下,Redis是异步的把数据导出到磁盘上。因为redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中,这种情况下,当Redis宕机的时候,最新的数据就丢了。

# 如果不希望丢掉任何一条数据的话就该用纯累加模式:一旦开启这个模式,Redis会把每次写入的数据在接收后都写入 appendonly.aof 文件。

# 每次启动时Redis都会把这个文件的数据读入内存里。

#

# 注意,异步导出的数据库文件和纯累加文件可以并存(此时需要把上面所有"save"设置都注释掉,关掉导出机制)。

# 如果纯累加模式开启了,那么Redis会在启动时载入日志文件而忽略导出的 dump.rdb 文件。

#

# 重要:查看 BGREWRITEAOF 来了解当累加日志文件太大了之后,怎么在后台重新处理这个日志文件。

# 设置:yes为纯累加模式

appendonly no

 

# 设置纯累加文件名字及保存路径,默认:"appendonly.aof"

# appendfilename appendonly.aof

 

# fsync() 请求操作系统马上把数据写到磁盘上,不要再等了。

# 有些操作系统会真的把数据马上刷到磁盘上;有些则要磨蹭一下,但是会尽快去做。

# Redis支持三种不同的模式:

#

# no:不要立刻刷,只有在操作系统需要刷的时候再刷。比较快。

# always:每次写操作都立刻写入到aof文件。慢,但是最安全。

# everysec:每秒写一次。折衷方案。

# 默认的 "everysec" 通常来说能在速度和数据安全性之间取得比较好的平衡。

# 如果你真的理解了这个意味着什么,那么设置"no"可以获得更好的性能表现(如果丢数据的话,则只能拿到一个不是很新的快照);

# 或者相反的,你选择 "always" 来牺牲速度确保数据安全、完整。

#

# 如果不确定这些模式的使用,建议使用 "everysec"

#

# appendfsync always

appendfsync everysec

# appendfsync no

 

# 如果AOF的同步策略设置成 "always" 或者 "everysec",那么后台的存储进程(后台存储或写入AOF日志)会产生很多磁盘I/O开销。

# 某些Linux的配置下会使Redis因为 fsync() 而阻塞很久。

# 注意,目前对这个情况还没有完美修正,甚至不同线程的 fsync() 会阻塞我们的 write(2) 请求。

#

# 为了缓解这个问题,可以用下面这个选项。它可以在 BGSAVE 或 BGREWRITEAOF 处理时阻止 fsync()。

#

# 这就意味着如果有子进程在进行保存操作,那么Redis就处于"不可同步"的状态。

# 这实际上是说,在最差的情况下可能会丢掉30秒钟的日志数据。(默认Linux设定)

#

# 如果你有延迟的问题那就把这个设为 "yes",否则就保持 "no",这是保存持久数据的最安全的方式。

no-appendfsync-on-rewrite no

 

# 自动重写AOF文件

# 如果AOF日志文件大到指定百分比,Redis能够通过 BGREWRITEAOF 自动重写AOF日志文件。

#

# 工作原理:Redis记住上次重写时AOF日志的大小(或者重启后没有写操作的话,那就直接用此时的AOF文件),

# 基准尺寸和当前尺寸做比较。如果当前尺寸超过指定比例,就会触发重写操作。

#

# 你还需要指定被重写日志的最小尺寸,这样避免了达到约定百分比但尺寸仍然很小的情况还要重写。

#

# 指定百分比为0会禁用AOF自动重写特性。

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

 

########## SLOW LOG 慢查询日志 ##########

 

# Redis慢查询日志可以记录超过指定时间的查询。运行时间不包括各种I/O时间。

# 例如:连接客户端,发送响应数据等。只计算命令运行的实际时间(这是唯一一种命令运行线程阻塞而无法同时为其他请求服务的场景)

#

# 你可以为慢查询日志配置两个参数:一个是超标时间,单位为微妙,记录超过个时间的命令。

# 另一个是慢查询日志长度。当一个新的命令被写进日志的时候,最老的那个记录会被删掉。

#

# 下面的时间单位是微秒,所以1000000就是1秒。注意,负数时间会禁用慢查询日志,而0则会强制记录所有命令。

slowlog-log-slower-than 10000

 

# 这个长度没有限制。只要有足够的内存就行。你可以通过 SLOWLOG RESET 来释放内存。

slowlog-max-len 128

 

########## VIRTUAL MEMORY 虚拟内存 ##########

 

### 警告!虚拟内存在Redis 2.4是反对的,因性能问题,2.4版本 VM机制彻底废弃,不建议使用此配置!!!!!!!!!!!

# 虚拟内存可以使Redis在内存不够的情况下仍然可以将所有数据序列保存在内存里。

# 为了做到这一点,高频key会调到内存里,而低频key会转到交换文件里,就像操作系统使用内存页一样。

# 要使用虚拟内存,只要把 "vm-enabled" 设置为 "yes",并根据需要设置下面三个虚拟内存参数就可以了。

vm-enabled no

 

# 这是交换文件的路径。估计你猜到了,交换文件不能在多个Redis实例之间共享,所以确保每个Redis实例使用一个独立交换文件。

# 最好的保存交换文件(被随机访问)的介质是固态硬盘(SSD)。

# *** 警告 *** 如果你使用共享主机,那么默认的交换文件放到 /tmp 下是不安全的。

# 创建一个Redis用户可写的目录,并配置Redis在这里创建交换文件。

vm-swap-file /tmp/redis.swap

 

# "vm-max-memory" 配置虚拟内存可用的最大内存容量。

# 如果交换文件还有空间的话,所有超标部分都会放到交换文件里。

# "vm-max-memory" 设置为0表示系统会用掉所有可用内存,建议设置为剩余内存的60%-80%。

# 将所有大于vm-max-memory的数据存入虚拟内存,无论vm-max-memory设置多小,所有索引数据都是内存存储的(Redis的索引数据就是keys),也就是说,当vm-max-memory设置为0的时候,其实是所有value都存在于磁盘。默认值为0。

vm-max-memory 0

 

# Redis交换文件是分成多个数据页的。

# 一个可存储对象可以被保存在多个连续页里,但是一个数据页无法被多个对象共享。

# 所以,如果你的数据页太大,那么小对象就会浪费掉很多空间。

# 如果数据页太小,那用于存储的交换空间就会更少(假定你设置相同的数据页数量)

# 如果你使用很多小对象,建议分页尺寸为64或32个字节。

# 如果你使用很多大对象,那就用大一些的尺寸。

# 如果不确定,那就用默认值 :)

vm-page-size 32

 

# 交换文件里数据页总数。

# 根据内存中分页表(已用/未用的数据页分布情况),磁盘上每8个数据页会消耗内存里1个字节。

# 交换区容量 = vm-page-size * vm-pages

# 根据默认的32字节的数据页尺寸和134217728的数据页数来算,Redis的数据页文件会占4GB,而内存里的分页表会消耗16MB内存。

# 为你的应验程序设置最小且够用的数字比较好,下面这个默认值在大多数情况下都是偏大的。

vm-pages 134217728

 

# 同时可运行的虚拟内存I/O线程数,即访问swap文件的线程数。

# 这些线程可以完成从交换文件进行数据读写的操作,也可以处理数据在内存与磁盘间的交互和编码/解码处理。

# 多一些线程可以一定程度上提高处理效率,虽然I/O操作本身依赖于物理设备的限制,不会因为更多的线程而提高单次读写操作的效率。

# 特殊值0会关闭线程级I/O,并会开启阻塞虚拟内存机制。

# 设置最好不要超过机器的核数,如果设置为0,那么所有对swap文件的操作都是串行的.可能会造成比较长时间的延迟,但是对数据完整性有很好的保证.

vm-max-threads 4

 

########## ADVANCED CONFIG 高级配置 ##########

 

# 当有大量数据时,适合用哈希编码(这会需要更多的内存),元素数量上限不能超过给定限制。

# Redis Hash是value内部为一个HashMap,如果该Map的成员数比较少,则会采用类似一维线性的紧凑格式来存储该Map, 即省去了大量指针的内存开销,如下2个条件任意一个条件超过设置值都会转换成真正的HashMap,

# 当value这个Map内部不超过多少个成员时会采用线性紧凑格式存储,默认是64,即value内部有64个以下的成员就是使用线性紧凑存储,超过该值自动转成真正的HashMap。

hash-max-zipmap-entries 512

# 当 value这个Map内部的每个成员值长度不超过多少字节就会采用线性紧凑存储来节省空间。

hash-max-zipmap-value 64

 

# 与hash-max-zipmap-entries哈希相类似,数据元素较少的情况下,可以用另一种方式来编码从而节省大量空间。

# list数据类型多少节点以下会采用去指针的紧凑存储格式

list-max-ziplist-entries 512

# list数据类型节点值大小小于多少字节会采用紧凑存储格式

list-max-ziplist-value 64

 

# 还有这样一种特殊编码的情况:数据全是64位无符号整型数字构成的字符串。

# 下面这个配置项就是用来限制这种情况下使用这种编码的最大上限的。

set-max-intset-entries 512

 

# 与第一、第二种情况相似,有序序列也可以用一种特别的编码方式来处理,可节省大量空间。

# 这种编码只适合长度和元素都符合下面限制的有序序列:

zset-max-ziplist-entries 128

zset-max-ziplist-value 64

 

# 哈希刷新,每100个CPU毫秒会拿出1个毫秒来刷新Redis的主哈希表(顶级键值映射表)。

# redis所用的哈希表实现(见dict.c)采用延迟哈希刷新机制:你对一个哈希表操作越多,哈希刷新操作就越频繁;

# 反之,如果服务器非常不活跃那么也就是用点内存保存哈希表而已。

# 默认是每秒钟进行10次哈希表刷新,用来刷新字典,然后尽快释放内存。

# 建议:

# 如果你对延迟比较在意的话就用 "activerehashing no",每个请求延迟2毫秒不太好嘛。

# 如果你不太在意延迟而希望尽快释放内存的话就设置 "activerehashing yes"。

activerehashing yes

 

########## INCLUDES 包含 ##########

 

# 包含一个或多个其他配置文件。

# 这在你有标准配置模板但是每个redis服务器又需要个性设置的时候很有用。

# 包含文件特性允许你引人其他配置文件,所以好好利用吧。

# include /path/to/local.conf

# include /path/to/other.conf

 

参考文献

官方主站:http://www.redis.io/

下载地址:http://www.redis.cn/download.html

Interactive Tutorial:http://try.redis-db.com/ 一步一步教你熟悉Redis的基本命令

Command API:http://redis.io/commands http://www.redis.cn/commands.html

客户端程序:http://redis.io/clients

Redis文档:http://redis.io/documentation

命令参考:http://manual.csser.com/redis/

Redis内存使用优化与存储:

http://www.infoq.com/cn/articles/tq-redis-memory-usage-optimization-storage

Redis复制与可扩展集群搭建:

http://www.infoq.com/cn/articles/tq-redis-copy-build-scalable-cluster

Redis资料汇总专题http://blog.nosqlfan.com/html/3537.html

将redis变成数据库:http://code.google.com/p/alchemydatabase/

类似的产品:http://code.google.com/p/memlink/

redis-dump,将Redis数据dump成json格式的工具:https://github.com/delano/redis-dump

博文最后更新时间:


评论

  • Fiona

    Hi there! This post could not be written any better! Going through this article reminds me of my previous roommate! He continually kept preaching about this http://crystaldreamsworld.com

  • Merziuz

    8dfdTZ http://pills2sale.com/ viagra online

  • Lyman

    I support Manchester United <a href="https://unef.edu.br/site/xd-cialis-sample-fi3h">comprare cialis online</a> At UF, one doctoral and two master's students are working with McCleery to collect data on fox squirrels. They are now in the final stage of a study looking at pine tree areas to find the best management programs to conserve this animal.

  • Roman

    Where are you calling from? <a href="https://unef.edu.br/site/ciprodex-online-pharmacy-abj6">ciprofloxacino es para el dolor de garganta</a> The impasse came amid a three-month drought in new stocklistings on the São Paulo Stock Exchange. Ser Educacional andshareholders had intended on Friday to price the IPO, with whichthey sought to raise up to 723.3 million reais ($333 million).

  • Forest

    I hate shopping <a href="http://adena.ro/v2/green-blender-reviews-q05a">green blender reviews</a> The officer said green paint had been tossed on the white marble statue of the 16th president that looks onto the National Mall, and that the memorial will reopen when it had been removed, likely later in the morning.

  • Edison

    Gloomy tales <a href="http://www.mamaloca.net/pharmacy/index.php/fluticasone-furoate-nasal-spray-boots-t8bj">salmeterol fluticasone seretide</a> Sawyer said in his report that while clearing the residence, including his conduct of a protective sweep to ensure there were no injured parties inside, he saw a handgun, with a live round stuck near its slide's ejection port, lying on the top of the stairs in the home's living room.

发表评论

博客统计

访问量:5264031

博文总数:750 评论总数:910100

原创126 翻译20 转载604