improve document

This commit is contained in:
fortrue 2017-08-29 21:17:06 +08:00
parent ae20d7681c
commit b3aba17748
3 changed files with 693 additions and 6 deletions

View File

@ -1,6 +1,6 @@
# Predixy
# Predixy [中文版](https://github.com/joyieldInc/predixy/blob/master/README_CN.md)
**Predixy** is a high performance and full features proxy for redis sentinel and redis cluster
**Predixy** is a high performance and fully featured proxy for redis sentinel and redis cluster
## Features
@ -11,6 +11,7 @@
+ Supports Redis Cluster.
+ Supports redis block command, eg:blpop, brpop, brpoplpush.
+ Supports scan command, even multi redis instances.
+ Multi-keys command support: mset/msetnx/mget/del/unlink/touch/exists.
+ Multi-databases support, means redis command select is avaliable.
+ Supports redis transaction, limit in Redis Sentinel single redis group.
+ Supports redis Scripts, script load, eval, evalsha.
@ -24,7 +25,7 @@
## Build
Predixy can be compiled and used on Linux, OSX, BSD, Windows([Cygwin](http://www.cygwin.com/)).
Predixy can be compiled and used on Linux, OSX, BSD, Windows([Cygwin](http://www.cygwin.com/)). Requires C++11 compiler.
It is as simple as:
@ -47,10 +48,16 @@ For examples:
$ make MT=false
$ make debug MT=false TS=true
## Install
Just copy src/predixy to the install path
$ cp src/predixy /path/to/bin
## Configuration
See below files:
+ predixy.conf, basic config.
+ predixy.conf, basic config, will refrence below config files.
+ cluster.conf, Redis Cluster backend config.
+ sentinel.conf, Redis Sentinel backend config.
+ auth.conf, authority control config.
@ -59,7 +66,7 @@ See below files:
## Running
$ ./predixy ../conf/predixy.conf
$ src/predixy conf/predixy.conf
With default predixy.conf, Predixy will listen at 0.0.0.0:7617 and
proxy to Redis Cluster 127.0.0.1:6379.
@ -70,7 +77,7 @@ So you will look mass log output, but you can still test it with redis-cli.
More command line arguments:
$ ./predixy -h
$ src/predixy -h
## Stats
@ -111,6 +118,9 @@ Reset all stats and latency monitors, require admin permission.
redis> CONFIG ResetStat
## Benchmark
predixy is fast, how fast? more than twemproxy, codis, redis-cerberus
See wiki
[benchmark](https://github.com/joyieldInc/predixy/wiki/Benchmark)

140
README_CN.md Normal file
View File

@ -0,0 +1,140 @@
# Predixy
**Predixy** 是一款高性能全特征redis代理支持redis-sentinel和redis-cluster
## 特性
+ 高性能并轻量级
+ 支持多线程
+ 多平台支持Linux、OSX、BSD、Windows([Cygwin](http://www.cygwin.com/))
+ 支持Redis Sentinel可配置一组或者多组redis
+ 支持Redis Cluster
+ 支持redis阻塞型命令包括blpop、brpop、brpoplpush
+ 支持scan命令无论是单个redis还是多个redis实例都支持
+ 多key命令支持: mset/msetnx/mget/del/unlink/touch/exists
+ 支持redis的多数据库即可以使用select命令
+ 支持事务当前仅限于Redis Sentinel下单一redis组可用
+ 支持脚本包括命令script load、eval、evalsha
+ 支持发布订阅机制也即Pub/Sub系列命令
+ 多数据中心支持,读写分离支持
+ 扩展的AUTH命令强大的读、写、管理权限控制机制健空间限制机制
+ 日志可按级别采样输出异步日志记录避免线程被io阻塞
+ 日志文件可以按时间、大小自动切分
+ 丰富的统计信息包括CPU、内存、请求、响应等信息
+ 延迟监控信息可以看到整体延迟分后端redis实例延迟
## 编译
Predixy可以在所有主流平台下编译推荐在linux下使用需要支持C++11的编译器。
编译非常简单下载或者git clone代码后进到predixy目录直接执行
$ make
编译后会在src目录生成一个可执行文件predixy
编译debug版本:
$ make debug
更多编译选项:
+ CXX=c++compiler指定c++编译器缺省是g++可以指定为其它例如CXX=clang++
+ EV=epoll|poll|kqueue指定异步io模型缺省情况下是根据平台来检测
+ MT=false, 关闭多线程支持
+ TS=true, 开启函数调用耗时分析,该选项仅用于开发模式
一些使用参数编译的例子:
$ make CXX=clang++
$ make EV=poll
$ make MT=false
$ make debug MT=false TS=true
## 安装
简单的只要拷贝src/predixy到目标路径即可
$ cp src/predixy /path/to/bin
## 配置 [详细文档](https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md)
predixy的配置类似redis, 具体配置项的含义在配置文件里有详细解释,请参考下列配置文件:
+ predixy.conf整体配置文件会引用下面的配置文件
+ cluster.conf用于Redis Cluster时配置后端redis信息
+ sentinel.conf用于Redis Sentinel时配置后端redis信息
+ auth.conf访问权限控制配置可以定义多个验证密码可每个密码指定读、写、管理权限以及定义可访问的健空间
+ dc.conf多数据中心支持可以定义读写分离规则读流量权重分配
+ latency.conf 延迟监控规则定义,可以指定需要监控的命令以及延时时间间隔
提供这么多配置文件实际上是按功能分开了,所有配置都可以写到一个文件里,也可以写到多个文件里然后在主配置文件里引用进来。
## 运行
$ src/predixy conf/predixy.conf
使用默认的配置文件predixy.conf predixy将监听地址0.0.0.0:7617后端的redis是Redis Cluster 127.0.0.1:6379。通常127.0.0.1:6379并不是运行在Redis Clusterr模式下因此Predixy将会有大量的错误日志输出。不过你依然可以用redis-cli连接predixy来试用一下
$ redis-cli -p 7617 info
执行上条命令后可以看到predixy自身的一些信息如果127.0.0.1:6379在运行的话你可以试试其它redis命令看看效果如何。
更多的启动命令行参数请看帮助:
$ src/predixy -h
## 统计信息
和redis一样predixy用INFO命令来给出统计信息。
在redis-cli连接下执行下面的命令
redis> INFO
你将看到类似redis执行INFO命令的输出不过这里是predixy的统计信息。
特别提一下predixy里面的延迟监控信息可以通过在配置里定义的延迟监控名来看延迟信息
redis> INFO Latency <latency-name>
下面是一个延迟信息输出的例子:
LatencyMonitorName:all
latency(us) sum(us) counts
<= 100 3769836 91339 91.34%
<= 200 777185 5900 97.24%
<= 300 287565 1181 98.42%
<= 400 185891 537 98.96%
<= 500 132773 299 99.26%
<= 600 85050 156 99.41%
<= 700 85455 133 99.54%
<= 800 40088 54 99.60%
<= 1000 67788 77 99.68%
> 1000 601012 325 100.00%
T 60 6032643 100001
The last line is total summary, 60 is average latency(us)
还可以单独看某个redis后端的延迟信息
redis> INFO ServerLatency <server-address> [latency-name]
要重置所有的统计信息和redis执行的命令是一样的不过predixy要求有管理权限才可以重置统计信息
redis> CONFIG ResetStat
## 性能评测
predixy很快有多快对比几个流行的redis代理(twemproxy,codis,redis-cerberus), predixy要比它们快得多。
具体比较参见Wiki
[benchmark](https://github.com/joyieldInc/predixy/wiki/Benchmark)
## 许可
Copyright (C) 2017 Joyield, Inc. <joyield.com#gmail.com>
All rights reserved.
License under BSD 3-clause "New" or "Revised" License

537
doc/config_CN.md Normal file
View File

@ -0,0 +1,537 @@
# Predixy配置文档说明
要正常运行predixy服务一个配置文件是必不可少的启动一个正常的predixy服务需执行以下命令
$ predixy <config-file> [--ArgName=ArgValue]...
predixy首先读取config-file文件中的配置信息如果有命令行参数指定的话则会用命令行参数的值覆盖配置文件中定义的相应值。
## 配置文件格式说明
配置文件是以行为单位的文本文件,每一行是以下几种类型之一
+ 空行或注释
+ Key Value
+ Key Value {
+ }
### 规则
+ 以#开始的内容为注释内容
+ Include是一个特殊的Key表示引用Value指明的文件如果不是绝对路径的话则相对路径是当前这个文件所在的路径
+ Value可以为空 如果Value本身包括#,双引号的话,应该用双引号括起来,里面的双引号加反斜杠转义, 例如: "A \"#special#\" value"
+ 多个行定义同一个Key的话最后出现的行会覆盖之前的定义
## 基本配置部分
### Name
定义predixy服务的名字在用INFO命令的时候会输出这个内容
例子:
Name PredixyUserInfo
### Bind
定义predixy服务监听的地址支持ip:port以及unix socket
例子:
Bind 0.0.0.0:7617
Bind /tmp/predixy
未指定时为: 0.0.0.0:7617
### WorkerThreads
指定工作线程数
例子:
WorkerThreads 4
未指定时为: 1
### MaxMemory
指定predixy最大可申请分配的内存可以带单位(G/M/K)指定为0时表示不限制
例子:
MaxMemory 1024000
MaxMemory 1G
未指定时为: 0
### ClientTimeout
指定客户端超时时间以秒为单位即客户端在空闲时间超过该时间以后将主动断开客户端连接为0时表示禁止该功能不主动断开客户端连接
例子:
ClientTimeout 300
未指定时为: 0
### BufSize
IO Buffer大小predixy内部分配BufSize大小的缓冲区用于接受客户端命令和服务端响应完全零拷贝的转发给服务端或者客户端该值太小的话影响性能太大的话浪费空间也可能对性能无益。但是具体多少合适要看实际应用场景predixy默认设该值为4096
例子:
BufSize 8192
未指定时为: 4096
### Log
指定日志文件名
例子:
Log /var/log/predixy.log
未指定时predixy的行为是将日志写向标准输出
### LogRotate
日志自动切分选项,可以按时间指定,也可以按文件大小指定,还可以两者都指定。按时间指定支持如下格式:
+ 1d 一天
+ nh 1<= n <= 24 n小时
+ nm 1 <= n <= 1440 n分钟
按文件大小指定支持G和M单位
例子:
LogRotate 1d #每天切分一次
LogRotate 1h #每小时切分一次
LogRotate 10m #每10分钟切分一次
LogRotate 2G #日志文件每2G切分一次
LogRotate 200M #日志文件每200M切分一次
LogRotate 1d 2G #每天切分一次且如果日志文件达到2G也切分一次
未定义时禁用该功能
### LogXXXSample
日志输出采样率表示每多少条该级别的日志输出一条到Log中为0时则表示不输出该级别日志。支持的级别如下
+ LogVerbSample
+ LogDebugSample
+ LogInfoSample
+ LogNoticeSample
+ LogWarnSample
+ LogErrorSample
例子:
LogVerbSample 0
LogDebugSample 0
LogInfoSample 10000
LogNoticeSample 1
LogWarnSample 1
LogErrorSample 1
这几个参数可以在线修改像redis一样通过config set命令:
CONFIG SET LogDebugSample 1
在predixy中执行config命令需要管理权限
## 权限控制配置部分
predixy扩展了redis中AUTH命令的功能支持定义多个认证密码可以为每个密码指定权限权限包括读权限、写权限和管理权限其中写权限包括读权限管理权限又包括写权限。还可以指定每个密码所能读写的健空间健空间的定义是指健具有某个前缀。
权限控制的定义格式如下:
Authority {
Auth [password] {
Mode read|write|admin
[KeyPredix Predix...]
[ReadKeyPredix Predix...]
[WriteKeyPredix Predix...]
}...
}
Authority里面可以定义多个Auth每个Auth指定一个密码可以为每个Auth定义权限和健空间。
参数说明:
+ Mode: 必须指定只能是read、write、admin三者之一分别表示读、写、管理权限
+ KeyPrefix: 可选项,可以定义健空间,多个健空间用空格隔开
+ ReadKeyPrefix: 可选项,可以定义可读的健空间,多个健空间用空格隔开
+ WriteKeyPrefix: 可选项,可以定义可写的健空间,多个健空间用空格隔开
对于可读的健空间如果定义了ReadKeyPrefix,则由ReadKeyPrefix决定,否则由KeyPrefix决定如果两者都没有则不限制。可写的健空间解释也一样。需要注意的是有写权限就表示有读权限但是读写健空间是完全独立的即WriteKeyPrefix不会默认包括ReadKeyPrefix的内容。
例子:
Authority {
Auth {
Mode read
KeyPrefix Info
}
Auth readonly {
Mode read
}
Auth modify {
Mode write
ReadPrefix User Stats
WritePrefix User
}
}
上面的例子定义了三个认证密码
+ 空密码因为密码为空所以这个认证是默认的认证它具有读权限由于指定了KeyPrefix因此它最终的权限是只能读取具有前缀Info的key
+ readonly密码这个认证具有读权限没有健空间限制它可以读所有key
+ modify密码这个认证具有写权限分别定义了可读健空间User和Stats,因此它能读取具有这两个前缀的key而可写健空间定义为User,因此它能写具有前缀User的key但是不能写具有前缀Stats的key
缺省的predixy权限控制定义如下
Authority {
Auth {
Mode write
}
Auth "#a complex password#" {
Mode admin
}
}
它表示无需密码即可读写所有的key但是管理权限要求输入密码#a complex password#
## redis实例配置部分
predixy支持Redis Sentinel和Redis Cluster来使用redis一个配置里这两种形式只能出现一种。
### Redis Sentinel形式
定义格式如下:
SentinelServerPool {
[Password xxx]
[Databases number]
Hash atol|crc16
[HashTag "xx"]
Distribution modula|random
[MasterReadPriority [0-100]]
[StaticSlaveReadPriority [0-100]]
[DynamicSlaveReadPriority [0-100]]
[RefreshInterval seconds]
[ServerFailureLimit number]
[ServerRetryTimeout seconds]
Sentinels {
+ addr
...
}
Group xxx {
[+ addr]
...
}
}
参数说明:
+ Password: 指定连接redis实例默认的密码不指定的情况下表示redis不需要密码
+ Databases: 指定redis db数量不指定的情况下为1
+ Hash: 指定对key算哈希的方法当前只支持atol和crc16
+ HashTag: 指定哈希标签,不指定的话为{}
+ Distribution: 指定分布key的方法当前只支持modula和random
+ MasterReadPriority: 读写分离功能从redis master节点执行读请求的优先级为0则禁止读redis master
+ StaticSlaveReadPriority: 读写分离功能从静态redis slave节点执行读请求的优先级所谓静态节点是指在本配置文件中显示列出的redis节点
+ DynamicSlaveReadPolicy: 功能见上所谓动态节点是指在本配置文件中没有列出但是通过redis sentinel动态发现的节点
+ RefreshInterval: predixy会周期性的请求redis sentinel以获取最新的集群信息该参数以秒为单位指定刷新周期
+ ServerFailureLimit: 一个redis实例出现多少次才错误以后将其标记为失效
+ ServerRetryTimeout: 一个redis实例失效后多久后去检查其是否恢复正常
+ Sentinels: 里面定义redis sentinel实例的地址
+ Group: 定义一个redis组Group的名字应该和redis sentinel里面的名字一致Group里可以显示列出redis的地址列出的话就是上面提到的静态节点
一个例子:
SentinelServerPool {
Databases 16
Hash crc16
HashTag "{}"
Distribution modula
MasterReadPriority 60
StaticSlaveReadPriority 50
DynamicSlaveReadPriority 50
RefreshInterval 1
ServerFailureLimit 10
ServerRetryTimeout 1
Sentinels {
+ 10.2.2.2
+ 10.2.2.3
+ 10.2.2.4
}
Group shard001 {
}
Group shard002 {
}
}
这个Redis Sentinel集群定义指定了三个redis sentinel实例分别是10.2.2.2、10.2.2.3、10.2.2.4定义了两组redis分别是shard001、shard002。没有指定任何静态redis节点。所有redis实例都没有开启密码认证它们都具有16个db。predixy用crc16计算key的哈希值然后通过modula也就是求模的办法将key分布到shard001或shard002中去。由于MasterReadPriority为60,比DynamicSlaveReadPriority的50要大所以读请求都会分发到redis master节点RefreshInterval为1,每一秒钟向redis sentinel发送请求刷新集群信息。redis实例失败累计达到10次后将该redis实例标记失效每间隔1秒钟后检查其是否恢复。
### Redis Cluster形式
定义格式如下:
ClusterServerPool {
[Password xxx]
[MasterReadPriority [0-100]]
[StaticSlaveReadPriority [0-100]]
[DynamicSlaveReadPriority [0-100]]
[RefreshInterval seconds]
[ServerFailureLimit number]
[ServerRetryTimeout seconds]
Servers {
+ addr
...
}
}
参数说明:
+ 可选的参数和Redis Sentinel模式同名参数含义一样
+ Servers:在这里列出redis cluster里的redis实例列出的为静态节点未列出而是通过集群信息发现的则为动态节点
一个例子:
ClusterServerPool {
MasterReadPriority 0
StaticSlaveReadPriority 50
DynamicSlaveReadPriority 50
RefreshInterval 1
ServerFailureLimit 10
ServerRetryTimeout 1
Servers {
+ 192.168.2.107:2211
+ 192.168.2.107:2212
}
}
该定义指定通过redis实例192.168.2.107:2211和192.168.2.107:2212来发现集群信息指定MasterReadPriority为0表示不要将读请求分发到redis master节点。
## 多数据中心配置部分
predixy支持多数据中心在redis部署跨数据中心的时候可以将读请求分发给本数据中心的redis实例避免跨数据中心访问。套用数据中心的概念实际上即便没有多数据中心也可以在需要从节点来分担读请求的时候通过本配置来控制请求分配此时比如可以认为一个机架就是一个数据中心。
多数据中心配置格式:
LocalDC name
DataCenter {
DC name {
AddrPrefix {
+ IpPrefix
...
}
ReadPolicy {
name priority [weight]
other priority [weight]
}
}
...
}
参数说明:
+ LocalDC: 指定当前predixy所在的数据中心
+ DC: 定义一个数据中心
+ AddrPrefix: 定义该数据中心包括的ip前缀
+ ReadPolicy: 定义从该数据中心读其它(包括自己)数据中心的优先级及权重
如果不用数据中心功能那么不提供LocalDC和DataCenter定义即可。
一个多数据中心配置的例子:
DataCenter {
DC bj {
AddrPrefix {
+ 10.1
}
ReadPolicy {
bj 50
sh 20
sz 10
}
}
DC sh {
AddrPrefix {
+ 10.2
}
ReadPolicy {
sh 50
bj 20 5
sz 20 2
}
}
DC sz {
AddrPrefix {
+ 10.3
}
ReadPolicy {
sz 50
sh 20
bj 10
}
}
}
这个例子定义了三个数据中心分别是bj、sh、sz。其中bj数据中心包括ip前缀为10.1的redis实例这样predixy通过redis sentinel或者redis cluster发现节点的时候如果看到redis实例的地址前缀是10.1则会认为该实例在bj数据中心。predixy根据自身所在的数据中心来选择相应的读请求策略。
假设predixy在bj数据中心bj读bj的优先级为50,高于另外两个所以predixy会优先选择bj数据中心进行读操作如果bj数据中心没有可用的redis节点则会是sh数据中心如果sh还没有节点才会选择sz。
假设predixy在sh数据中心predixy优先选择sh数据中心如果sh数据中心没有可用的redis实例因为bj和sh的优先级都为20,那么则会根据权重设置来分配流量在这里5份的请求去bj数据中心2份的请求去sz。
前面在定义集群的时候有说过可以定义主从节点的读优先级数据中心这里又有读优先级的概念那么它们是如何工作的原则就是在启用了数据中心的功能之后先根据数据中心读策略选取数据中心、然后再在数据中心内应用集群的主从读优先级选择最终的redis实例。
## 延迟监控配置部分
predixy提供了强大的延迟监控的功能可以记录predixy处理请求的时间对predixy来说这个时间其实主要就是请求redis的时间。
延迟监控定义格式如下:
LatencyMonitor name {
Commands {
+ cmd
[- cmd]
...
}
TimeSpan {
+ TimeElapsedUS
...
}
}
参数说明:
+ LatencyMonitor: 定义一个延迟监控
+ Commands: 指定该延迟监控记录哪些redis命令+ cmd表示监控该命令- cmd表示不监控该命令如果cmd为all则表示所有命令。
+ TimeSpan: 定义延迟桶,以微秒为单位,必须是一个严格递增的序列。
可以定义多个LatencyMonitor以便监控不同的命令。
延迟监控配置例子:
LatencyMonitor all {
Commands {
+ all
- blpop
- brpop
- brpoplpush
}
TimeSpan {
+ 1000
+ 1200
+ 1400
+ 1600
+ 1700
+ 1800
+ 2000
+ 2500
+ 3000
+ 3500
+ 4000
+ 4500
+ 5000
+ 6000
+ 7000
+ 8000
+ 9000
+ 10000
}
}
LatencyMonitor get {
Commands {
+ get
}
TimeSpan {
+ 100
+ 200
+ 300
+ 400
+ 500
+ 600
+ 700
+ 800
+ 900
+ 1000
}
}
LatencyMonitor set {
Commands {
+ set
+ setnx
+ setex
}
TimeSpan {
+ 100
+ 200
+ 300
+ 400
+ 500
+ 600
+ 700
+ 800
+ 900
+ 1000
}
}
上面的例子定义了三个延迟监控其中all监控除了blpop/brpop/brpoplpush外的所有命令get监控get命令set监控set/setnx/setex命令。这里的耗时桶定义并不适用与所有情况在实际使用的时候需要调整以更精确的反应真实的耗时情况。
查看耗时监控通过INFO命令来查看有三种使用方式
### 查看所有延迟定义的整体信息
命令:
redis> INFO
此时看到的结果列在最后的就是整体的延迟信息。
### 查看单个延迟定义的信息
命令:
redis> INFO Latency <name>
其中<name>为延迟定义名称结果会显示该定义的整体延迟信息以及分后端redis实例的延迟信息。
### 查看某个后端redis实例延迟信息
命令:
redis> INFO ServerLatency <serv> [name]
其中<serv>为redis实例地址[name]为可选的延迟定义名称如果忽略name那么就会给出请求该redis实例所有延迟定义信息否则只给出name的。
延迟信息格式说明下面是延迟定义all的整体信息一个例子
LatencyMonitorName:all
<= 100 3769836 91339 91.34%
<= 200 777185 5900 97.24%
<= 300 287565 1181 98.42%
<= 400 185891 537 98.96%
<= 500 132773 299 99.26%
<= 600 85050 156 99.41%
<= 700 85455 133 99.54%
<= 800 40088 54 99.60%
<= 1000 67788 77 99.68%
> 1000 601012 325 100.00%
T 60 6032643 100001
+ 第一列为<=,则第二列表示小于等于该耗时,第三列表示这个范围耗时的总和,第四列表示请求数,第五列表示累计的请求占总请求的百分比,
+ 第一列为>,则第二列表示大于该耗时的请求,后两列含义同上。本行最多只会出现一次,如果位于本行的请求数过多,则说明延迟定义指定的耗时桶不够合适。
+ 第一列为T这一行只会出现一次且总在最后。第二列表示所有请求的平均耗时第三列表示总的请求耗时之和第四列表示总的请求数。