首页 > 代码库 > Redis原理及基本应用

Redis原理及基本应用

CAP定理:

    C:Consistency 一致性,分布式系统中数据备份节点都需要实时保持数据一致性;

    A:Availability 可用性,集群中有节点发生故障,并不影响整个集群对外提供服务;

    P:Partition tolerance 分区容错性,系统数据部分丢失后,仍能提供服务。

    

在一个分布式系统中,CAP三者不能兼得;高可用、数据一致是很多系统设计的目标,但是分区的现象是不可避免的事情:

    CA:分区的现象是始终存在的,一般得CA系统指的是在各分区后的子分区内保持CA;

    CP:系统保持强一致性,在同步各节点之间数据中,无法做到多外提供服务,在关系型数据库事务中,就能体现CP的特性;

    AP:保证高可用,就必须放弃强一致性。一旦集群中发生分区现象,每个节点都能使用自己的本地数据对外提供服务,但是这样会导致全局数据的不一致性,NoSQL都基本数据此特性。

技术分享

    由于网络硬件等问题,造成延迟丢包的现象肯定会发生,所以分区容忍性是我们必须要实现的。在设计分布式系统中,只能在一致性和可用性之间做权衡。


BASE方案:

    BA(Basically Available) 基本可用,分布式系统出现故障时,允许损失部分可用性,保证核心可用;

    S(Soft state) 软状态,指允许系统出现中间状态,不会影响系统整体可用性;

    E(Eventually consistent) 最终一致,系统中所有数据副本经过一段时间后,最终能够达到一致的状态。

 

NoSQL主要的四种技术流派:

    K/V存储:key-value,如Dynamo、Redis;

    Column Family:列式数据库,如HBase;

    Document:文档数据库,如mongoDB;

    GraphDB:图式数据库。


Redis:Remote DICtionary Server:数据结构服务器。

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可以登录交互式命令行界面:

    [root@node7 ~]# systemctl start redis.service      

      [root@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-keepalive 300

    daemonize no    #是否以守护方式运行

    supervised no

    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-error yes

    rdbcompression yes     #本地数据是否压缩

    rdbchecksum yes

    dbfilename dump.rdb    #本地数据库名,默认为dump.rdb

    dir /var/lib/redis       #本地数据库存放路径

    slaveof <masterip> <masterport>  #本机为slave时,指定的master地址及端口号

    masterauth <master-password>  #slave连接master的密码

    slave-serve-stale-data yes

    slave-read-only yes

    repl-diskless-sync no

    repl-diskless-sync-delay 5

    repl-disable-tcp-nodelay no

    slave-priority 100

    requirepass foobared    #设置redis连接密码

    maxclients 10000   #同一时间最大客户端连接数

    maxmemory <bytes>   #指定redis最大可使用内存空间

    appendonly no   #指定是否在每次更新操作后进行日志记录

    appendfilename "appendonly.aof"   #更新日志文件名

    appendfsync everysec   #指定更新日志条件:no表示等操作系统进行数据缓存同步到磁盘;always每次更新操作后手动低啊用fsync()将数据写进磁盘;everysec每秒同步一次

    no-appendfsync-on-rewrite no

    auto-aof-rewrite-percentage 100

    auto-aof-rewrite-min-size 64mb

    aof-load-truncated yes

    lua-time-limit 5000

    slowlog-log-slower-than 10000

    slowlog-max-len 128

    latency-monitor-threshold 0

    notify-keyspace-events ""

    hash-max-ziplist-entries 512  

    hash-max-ziplist-value 64

    list-max-ziplist-size -2

    list-compress-depth 0

    set-max-intset-entries 512

    zset-max-ziplist-entries 128

    zset-max-ziplist-value 64

    hll-sparse-max-bytes 3000

    activerehashing yes

    client-output-buffer-limit normal 0 0 0

    client-output-buffer-limit slave 256mb 64mb 60

    client-output-buffer-limit pubsub 32mb 8mb 60

    hz 10

    aof-rewrite-incremental-fsync yes


Redis 发布订阅

    Redis 发布订阅分为发送消息端(pub),接收信息端(sub)。

技术分享

技术分享

  

    示例:

    (1) 创建一个订阅频道WeChat:

    127.0.0.1:6379> SUBSCRIBE WeChat

    Reading messages... (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

    Reading messages... (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 SET requirepass "hisen"     #设置密码为hisen

    OK

    127.0.0.1:6379> CONFIG GET requirepass             #查看密码

    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回复的错误信息



    示例:                                                                                  

    [root@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.81 requests 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.81 requests per second

      

    [root@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


本文出自 “DevOps” 博客,请务必保留此出处http://hisen2devops.blog.51cto.com/10109340/1909364

Redis原理及基本应用