CAP定理:
C:Consistency 一致性,分布式系统中数据备份节点都需要实时保持数据一致性;
A:Availability 可用性,集群中有节点发生故障,并不影响整个集群对外提供服务;
P:Partition tolerance 分区容错性,系统数据部分丢失后,仍能提供服务。
在一个分布式系统中,CAP三者不能兼得;高可用、数据一致是很多系统设计的目标,但是分区的现象是不可避免的事情:
CA:分区的现象是始终存在的,一般得CA系统指的是在各分区后的子分区内保持CA;
CP:系统保持强一致性,在同步各节点之间数据中,无法做到多外提供服务,在关系型数据库事务中,就能体现CP的特性;
AP:保证高可用,就必须放弃强一致性。一旦集群中发生分区现象,每个节点都能使用自己的本地数据对外提供服务,但是这样会导致全局数据的不一致性,NoSQL都基本数据此特性。
由于网络硬件等问题,造成延迟丢包的现象肯定会发生,所以分区容忍性是我们必须要实现的。在设计分布式系统中,只能在一致性和可用性之间做权衡。
BASE方案:
BA(Basically Available)基本可用,分布式系统出现故障时,允许损失部分可用性,保证核心可用;
S(Softstate) 软状态,指允许系统出现中间状态,不会影响系统整体可用性;
E(Eventually consistent)最终一致,系统中所有数据副本经过一段时间后,最终能够达到一致的状态。
NoSQL主要的四种技术流派:
K/V存储:key-value,如Dynamo、Redis;
Column Family:列式数据库,如HBase;
Document:文档数据库,如mongoDB;
GraphDB:图式数据库。
Redis:Remote DICtionaryServer:数据结构服务器。
Redis的特点:
(1) 完全开源免费,遵守BSD协议;
(2) 支持数据持久化存储;
(3) 支持数据备份。
Redis的优势:
(1) 性能高— 110000次/s的读速度,81000次/s的写速度;
(2) 支持的数据类型多— 有字符串(String),哈希(Hash),列表(List),集合(Sets),有序集合(Sorted sets)等类型的值。
(3) 原子性— 所有的操作都是原子性的;
(4) 特性丰富— 支持publish/subscribe、通知、key过期等特性。
Redis安装:3.0以上版本,需要到官网下载rpm包。
安装Redis的rpm包需要依赖到jemalloc安装包,所以需要配置好epel的yum源:
yum install ./redis-3.2.3-1.el7.x86_64.rpm
Redis配置:
Redis的配置文件为/etc/redis.conf,默认的监听端口为TCP的6379,通过rediscli可以登录交互式命令行界面:
[iyunv@node7 ~]# systemctl startredis.service
[iyunv@node7 ~]# redis-cli
127.0.0.1:6379>
Redis数据类型:
Redis支持五中数据类型:字符串(String),哈希(Hash),列表(List),集合(Sets),有序集合 (Sorted sets)。
(1) 字符串(String)
127.0.0.1:6379> SET name 'hisen' #设置一个字符串的key为name,value为hisen
OK #设置结果状态为OK
127.0.0.1:6379> GET name #获取key为name的值
"hisen" #获取的结果
注意:一个键最大能存储512MB。
(2) 哈希(Hash)
Hash类型为一键多值型,一个键对应一个集合的值,命令HMSET、HGETALL。
127.0.0.1:6379>HMSET hisen id name age gender
OK
127.0.0.1:6379>HGETALL hisen
1)"id"
2)"name"
3)"age"
4)"gender"
每个hash可以存储2^32-1个键值对。
(3) 列表(List)
列表类型值,可以从左边或者右边加入字符串列表中,命令LPUSH、RPUSH、LRANGE:
127.0.0.1:6379>LPUSH friends he
(integer)1
127.0.0.1:6379>LPUSH friends tao
(integer)2
127.0.0.1:6379>LPUSH friends ying
(integer)3
127.0.0.1:6379>RPUSH friends yu
(integer)4
127.0.0.1:6379>RPUSH friends zhen
(integer)5
127.0.0.1:6379>LRANGE friends 0 4
1)"ying"
2)"tao"
3)"he"
4)"yu"
5)"zhen"
每个列表最多可存储2^32-1个元素。
(4) 集合(Sets)
Set是string类型的无序集合,命令SADD 、SMEMBERS。
添加一个String元素,成功返回1,如果插入的元素与集合中某元素相同,则返回0。
127.0.0.1:6379>SADD animals cat
(integer)1
127.0.0.1:6379>SADD animals pig
(integer)1
127.0.0.1:6379>SADD animals dog
(integer)1
127.0.0.1:6379>SADD animals panda
(integer)1
127.0.0.1:6379>SADD animals dog
(integer)0
127.0.0.1:6379>SMEMBERS animals
1)"pig"
2)"panda"
3)"cat"
4)"dog"
(5) ZSET 有序集合 (Sorted sets)
ZSET也是string类型元素集合,而且不重复;
每个元素加入集合中时都会关联一个double类型的分数,Redis就是通过分数来对集合元素进行从大到小的排序,分数可以相同。
127.0.0.1:6379>ZADD animals 0 pig
(integer)1
127.0.0.1:6379>ZADD animals 2 cat
(integer)1
127.0.0.1:6379>ZADD animals 4 dog
(integer)1
127.0.0.1:6379>ZADD animals 6 panda
(integer)1
127.0.0.1:6379>ZRANGEBYSCORE animals 0 10
1)"pig"
2)"cat"
3)"dog"
4)"panda"
Redis 配置:
Redis的配置文件为安装目录下的redis.conf文件,也可以通过命令行来查看:
127.0.0.1:6379>CONFIG GET *
1) "dbfilename"
2) "dump.rdb"
3) "requirepass"
4) "hisen"
5) "masterauth"
6) ""
7) "unixsocket"
8) ""
9) "logfile"
10) "/var/log/redis/redis.log"
11) "pidfile"
12) "/var/run/redis/redis.pid"
13) "slave-announce-ip"
14) ""
15) "maxmemory"
16) "0"
17) "maxmemory-samples"
18) "5"
19) "timeout"
20) "0"
21) "auto-aof-rewrite-percentage"
22) "100"
23) "auto-aof-rewrite-min-size"
24) "67108864"
25) "hash-max-ziplist-entries"
26) "512"
27) "hash-max-ziplist-value"
28) "64"
29) "list-max-ziplist-size"
30) "-2"
31) "list-compress-depth"
32) "0"
…
redis.conf配置文件项:
bind 0.0.0.0 #监听端口
protected-mode yes
port 6379 #默认监听端口
tcp-backlog 511
timeout 0 #超时时间,0为不超时
tcp-keepalive300
daemonize no #是否以守护方式运行
supervisedno
pidfile /var/run/redis/redis.pid #存放pid的文件
loglevel notice #日志记录级别:debug、verbose、notice、warning
logfile /var/log/redis/redis.log #日志存放的文件
databases 16 #数据库数量
save 900 1 #指定900s内,有1次更新,就将数据同步到磁盘文件中
save 300 10 #指定300s内,有10次更新,就将数据同步到磁盘文件中
save 60 10000 #指定60s内,有10000次更新,就将数据同步到磁盘文件中
stop-writes-on-bgsave-erroryes
rdbcompression yes #本地数据是否压缩
rdbchecksumyes
dbfilename dump.rdb #本地数据库名,默认为dump.rdb
dir /var/lib/redis #本地数据库存放路径
slaveof <masterip><masterport> #本机为slave时,指定的master地址及端口号
masterauth <master-password> #slave连接master的密码
slave-serve-stale-datayes
slave-read-onlyyes
repl-diskless-syncno
repl-diskless-sync-delay5
repl-disable-tcp-nodelayno
slave-priority100
requirepass foobared #设置redis连接密码
maxclients 10000 #同一时间最大客户端连接数
maxmemory <bytes> #指定redis最大可使用内存空间
appendonly no #指定是否在每次更新操作后进行日志记录
appendfilename"appendonly.aof" #更新日志文件名
appendfsync everysec #指定更新日志条件:no表示等操作系统进行数据缓存同步到磁盘;always每次更新操作后手动低啊用fsync()将数据写进磁盘;everysec每秒同步一次
no-appendfsync-on-rewriteno
auto-aof-rewrite-percentage100
auto-aof-rewrite-min-size64mb
aof-load-truncatedyes
lua-time-limit5000
slowlog-log-slower-than10000
slowlog-max-len128
latency-monitor-threshold0
notify-keyspace-events""
hash-max-ziplist-entries 512
hash-max-ziplist-value64
list-max-ziplist-size-2
list-compress-depth0
set-max-intset-entries512
zset-max-ziplist-entries128
zset-max-ziplist-value64
hll-sparse-max-bytes3000
activerehashingyes
client-output-buffer-limitnormal 0 0 0
client-output-buffer-limitslave 256mb 64mb 60
client-output-buffer-limitpubsub 32mb 8mb 60
hz10
aof-rewrite-incremental-fsyncyes
Redis 发布订阅 Redis发布订阅分为发送消息端(pub),接收信息端(sub)。 
示例:
(1) 创建一个订阅频道WeChat:
127.0.0.1:6379>SUBSCRIBE WeChat
Readingmessages... (press Ctrl-C to quit)
1)"subscribe"
2)"WeChat"
3)(integer) 1
(2)另外开启一个客户端,并对WeChat频道进行信息发布:
127.0.0.1:6379>PUBLISH WeChat "Today is a funny day!"
(integer)1
127.0.0.1:6379>PUBLISH WeChat "I Love Linux!"
(integer)1
(3) 返回订阅客户端查看:
127.0.0.1:6379>SUBSCRIBE WeChat
Readingmessages... (press Ctrl-C to quit)
1)"subscribe"
2)"WeChat"
3)(integer) 1
1)"message"
2)"WeChat"
3)"Today is a funny day!"
1)"message"
2)"WeChat"
3)"I Love Linux!"
命令 | 描述 | PSUBSCRIBE pattern [pattern ...] | 订阅一个或多个符合模式的频道 | PUBSUB subcommand [argument [argument ...]] | 查看订阅与发布系统状态 | PUBLISH channel message | 将信息发送给指定频道 | PUNSUBSCRIBE [pattern [pattern ...]] | 退订所有给定模式的频道 | SUBSCRIBE channel [channel ...] | 订阅给定的一个或多个频道信息 | UNSUBSCRIBE [channel [channel ...]] | 退订给定的频道 |
Redis 事务:
事务隔离性:一个事务中的所有命令都会按顺序执行,执行事务时不会被其他客户端发来的命令打断;
事务原子性:事务中的命令,要么全部执行,要么全部不执行。
示例:
MULTI是开启一个事务的标识,之后多个命令会在事务中列队,等执行EXEC时,列队中的所有命令再依次执行。
127.0.0.1:6379>MULTI
OK
127.0.0.1:6379>SET name hisen
QUEUED
127.0.0.1:6379>GET name
QUEUED
127.0.0.1:6379>SADD xingshi zhao qiao sun li
QUEUED
127.0.0.1:6379>SMEMBERS xingshi
QUEUED
127.0.0.1:6379>EXEC
1)OK
2)"hisen"
3)(integer) 4
4)1) "qiao"
2) "li"
3) "sun"
4) "zhao"
命令 | 描述 | DISCARD | 取消事务 | EXEC | 执行事务 | MULTI | 开始一个事务 | UNWATCH | 取消对所有key的监控 | WATCH key [key ...] | 监控key,如果在事务执行前key被更改,事务将会被打断 |
Redis安全:
设置服务连接密码,可以通过配置文件,也可以通过命令行设置:
(1)查看Redis是否启用密码验证:
127.0.0.1:6379>CONFIG GET requirepass
1)"requirepass"
2) "" #空字符串代表没设置验证密码
(2)设置Redis密码验证:
127.0.0.1:6379> CONFIG SETrequirepass "hisen" #设置密码为hisen
OK
127.0.0.1:6379> CONFIG GETrequirepass #查看密码
1)"requirepass"
2) "hisen" #密码已设置,为hisen
(3)验证密码有效性:
127.0.0.1:6379> GET name #没输密码前,试图获取数据
(error) NOAUTH Authentication required. #显示没有认证的错误
127.0.0.1:6379> AUTH hisen #输入认证密码
OK #状态为OK
127.0.0.1:6379> GET name #再次获取数据
"hisen" #正确返回数据
Redis性能测试工具之redis-benchmark
redis-benchmark [option] [option value]
redis-benchmark选项:
选项 | 描述 | 默认值 | -h | 指定主机名 | 127.0.0.1 | -p | 指定端口 | 6379 | -s | 服务器socket |
| -c | 并发连接数 | 50 | -n | 请求数 | 10000 | -d | 以字节的形式指定SET/GET值的数据大小 | 2 | -k | 1=keep alive 0=reconnect | 1 | -r | SET/GET/INCR使用随机key,SADD使用随机值 |
| -P | 通过管道传输<numreq>请求 | 1 | -q | 强制退出redis。仅显示query/sec值 |
| --csv | 以CSV格式输出 |
| -l | 生成循环,永久执行测试 |
| -t | 仅运行以逗号分隔的测试命令列表 |
| -l | ldle模式,仅打开N个idle连接并等待 |
| -a | 指定认证密码 |
| -dbnum | 选择数据库号 | 0 | -e | 标准输出server回复的错误信息 |
|
示例:
[iyunv@node7~]# redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -c 100 -n 10000
======SET ======
10000 requests completed in 0.07 seconds
100 parallel clients
3 bytes payload
keep alive: 1
98.23%<= 1 milliseconds
100.00%<= 1 milliseconds
147058.81requests per second
======LPUSH ======
10000 requests completed in 0.07 seconds
100 parallel clients
3 bytes payload
keep alive: 1
99.51%<= 1 milliseconds
100.00%<= 1 milliseconds
147058.81requests per second
[iyunv@node7~]# redis-benchmark -h 127.0.0.1 -p 6379 -t set,lpush -c 100 -n 10000 -q
SET:144927.55 requests per second
LPUSH:151515.16 requests per second
|