抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

[toc]

redis 常用功能


KV cache and store
REmote DIctionary Server(远程字典服务器)
redis 运行都在内存中来实现,周期性的写入磁盘,来实现持久功能;

基本知识

KV cache and store
    in-memory;
    持久化 ;
    主从(借助于sentinal实现一定意义上的HA);
    Clustering(分布式);
数据结构服务器:
    String, List, Hash, Set, Sorted Set, Bitmap,HperLoglogs;
Memcached 与 Redis的区别:
    1、Memcached 是一个分布式的内存对象缓存系统;
    2、Reis 可以实现持久存储的;
    3、Mecached 是一个LUR 缓存,将过期数据清理出去;
    4、Redis支持更多的数据类型;
    5、Memcached 是多线程;
    6、Redis是单线程;
    7、二者的性能不相上下;
Redis 3.0的LRU算法的改进:
    预设随机取5个样本,插入并排序至一个pool, 移除最佳者,如此反复;
    走到内存用理小于maxmemory的设定;
    样本5比先前的3多;
    从局部最优趋向全局最优;
存储系统三类:
    RDBMS
    NoSQL:
        KV NoSQL: redis
        Column Family NoSQL: HBase
        Documentation NoSQL: MongoDB
        Graph NoSQL: Neo4j
    NewSQL(支持分布式)
Redis的组件:
    redis.io(官方站点)

Commands

redis-server
redis-cli
    Command line interface 
redis-benchmark
    Benchmarking utility
redis-check-dump & redis-check-aof
    Corrupted RDB/AOF files utilities

Redis守护进程

# vim /etc/redis.conf
监听6379端口;
tcp-backlog 511 #是redis守护进程的等队列,当并发较高时,再找位置来缓存新请求;
bind # 是指监听的地址;
bind 127.0.0.1 172.16.55.128
unixsocket /tmp/redis.sock # 当服务和redis在一台服务器上使用socket来通信,提高效率;
unixsocketperm 700
timeout #当一个客端连接多久后,认为超时,0表示禁用,认为一直存在;
tcp-keepaoive 0
loglevel notice
logfile /var/log/redis/redis.log
databases 16  # 表示可以使用多少个数据库;
save <sencods> <changes> # 如果多少秒发生多少变化则存储,因此这取决于业务模型;
save ""   #这样写表示禁用redis持久化功能;
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes 
rdbcompression yes
dbcheksum yes
dbfilename dump.rdb
dir /var/lib/redis
# 配置以为成为从服务器
salveof   ip # 这里指定主服务器的ip即可;
maxclients 100000
appendonly yes # 开启appendonly 持久化功能;
appendfsync  everysec # 是否使用fsync来持久化;
# redis服务端的参数,大多可以在redis-cli连接到服务器后进行动态修复或修改的;

redis-cli 常用命令

# redis-cli -p 25612 
127.0.0.1:25612> AUTH xxxxxxx
127.0.0.1:25612> HELP APPEND # help 用来查看帮助
127.0.0.1:25612> CLIENT LIST
id=3 addr=127.0.0.1:25666 fd=5 name= age=275 idle=0 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=client
127.0.0.1:25612> SELECT 1 # 第开第几个数据库,也可以理解成为名称空间;
127.0.0.1:25612> SELECT 1
OK
127.0.0.1:25612[1]> SET disto fedora
OK
127.0.0.1:25612[1]> GET disto
"fedora"
127.0.0.1:25612[1]> SET disto centos
OK
127.0.0.1:25612[1]> STRLEN disto
(integer) 6
127.0.0.1:25612[1]> DECR count
(integer) -1
127.0.0.1:25612[1]> DECR count
(integer) -2
127.0.0.1:25612[1]> DECR count
(integer) -3
127.0.0.1:25612[1]> SET disto gentoo NX # 显示为未能执行的操作,该值不存在则设定;
(nil)
127.0.0.1:25612[1]> SET foo bar XX # 该值则在则设定;
(nil)
127.0.0.1:25612[1]> SADD w1 mon tue wed thu sat sun
(integer) 6
127.0.0.1:25612[1]> SADD w1 mon tue wed thu fre sat sun
(integer) 1
127.0.0.1:25612[1]> 
127.0.0.1:25612[1]> SADD w2 tue thu day
127.0.0.1:25612[1]> ZADD weekday1 1 mon 2 tue 3 wed
(integer) 3
127.0.0.1:25612[1]> ZCARD weekday1
(integer) 3
127.0.0.1:25612[1]> ZRANK weekday1 tue
(integer) 1
127.0.0.1:25612[1]> ZRANK weekday1 mon
(integer) 0

(integer) 3
127.0.0.1:25612[1]> SINTER w1 w2 # 求两个集合的交集;
1) "thu"
2) "tue"
127.0.0.1:25612[1]> SUNION w1 w2  # 求两个集合的并集;
1) "sun"
2) "wed"
3) "sat"
4) "day"
5) "tue"
6) "thu"
7) "mon"
8) "fre"
127.0.0.1:25612[1]> SPOP w1 # 弹出一个元素 ;
"tue"
127.0.0.1:25612[1]> SPOP w1
"sun"
127.0.0.1:25612[1]> SISMEMBER w1 day # 表示已经没有这个元素;
(integer) 0
127.0.0.1:25612[1]> SISMEMBER w1 sat
(integer) 1
127.0.0.1:25612[1]> ZRANGE weekday1 0 1
1) "mon"
2) "tue"
127.0.0.1:25612[1]> HSET h1 a mon
(integer) 0
127.0.0.1:25612[1]> HGET h1 a
"mon"
127.0.0.1:25612[1]> HSET h1 b tue
(integer) 1
127.0.0.1:25612[1]> HGET h1 a 
"mon"
127.0.0.1:25612[1]> HGET h1 b 
"tue"
127.0.0.1:25612[1]> HVALS h1
1) "mon"
2) "tue"
127.0.0.1:25612[1]> HKEYS h1
1) "a"
2) "b"
Strings: 字串
    SET key value [EX #]  [NX|XX]
    GET
    INCR
    DECR
    EXIST
Lists: 列表
    LPUSH
    RPUSH
    LDROP
    RPOP
    LINDEX
    LSET
Sets: 集合
    SADD
    SINTER
    SUNTON
    SPOP
    SISMEMBER
Sorted Sets 有序集合, 其命令都以Z开头
    ZADD 
    ZRANGE
    ZCARD
    ZRANK
Hashes: 一组关联数的集合
    HSET
    HSETNX
    HGET 
    HKEYS
    HVALS
    HDEL

认证实现方法

(1) redis.conf
    requirepass PASSWORD
(2) redis-cli
    AUTH PASSWD

清空数据库

# FLUSHDB:  清空当前库
# FLUSHALL: 清空所有库

事务

# 通过MULTI, EXEC, WATCH等命令实现事务功能;
# 将一个或多个命令归并为一个操作提请服务器按顺序执行的机制;
# Redis数据不支持回滚操作;
# MULTI: 启动一个事务,中间的所有命令会放置在队列中;
# EXEC: 执行事务;
#  一次性将事务中的所有操作执行完成后返回给客户端;
127.0.0.1:25612> MULTI
OK
127.0.0.1:25612> SET ip 172.16.55.123
QUEUED
127.0.0.1:25612> GET ip 
QUEUED
127.0.0.1:25612> SET port 8080
QUEUED
127.0.0.1:25612> GET port 
QUEUED
127.0.0.1:25612> EXEC
1) OK
2) "172.16.55.123"
3) OK
4) "8080"
# WATCH: 乐观锁, 在EXEC命令执行之间有用于监视指定数量键;
    #如果监视中的某任意键数据被修改,则服务器拒绝执行事务;
# 打开两个终端
term1
127.0.0.1:25612> WATCH ip
OK
127.0.0.1:25612> MULTI
OK
127.0.0.1:25612> SET ip 10.0.0.1
QUEUED
127.0.0.1:25612> GET ip
QUEUED
term2 
127.0.0.1:25612> GET ip 
"172.16.55.123"
127.0.0.1:25612> SET ip 172.16.55.123
OK
127.0.0.1:25612> GET ip 
"172.16.55.123"
term1
127.0.0.1:25612> EXEC
(nil)
# 监控的一个键,EXEC之前键发生了改动,EXEC将拒绝提交;

Connection相关的命令:

AUTH
127.0.0.1:25612> HELP PING 

  PING [message]
  summary: Ping the server
  since: 1.0.0
  group: connection

127.0.0.1:25612> PING
PONG
127.0.0.1:25612> ECHO "hello redis"
"hello redis"
127.0.0.1:25612> 
QUIT
127.0.0.1:25612> HELP @connection

Server相关的命令

CLIENT GETNAME
CLIENT KILL ip:port
127.0.0.1:25612> CLIENT SETNAME localconn
OK
127.0.0.1:25612> CLIENT GETNAME
"localconn"
127.0.0.1:25612> HELP INFO # 获取当前服务器的状态及信息;
  INFO [section]
  summary: Get information and statistics about the server
  since: 1.0.0
  group: server
127.0.0.1:25612> INFO CPU
# CPU
used_cpu_sys:474.20
used_cpu_user:258.88
used_cpu_sys_children:0.01
used_cpu_user_children:0.00
CONFIG RESETSTAT
CONFIG SET PARAMETER value
CONFIG REWRITE 
DBSIZE
# 跟持久化相关的数据 
BGSAVE 
SAVE
LASTSAVE
monitor # 实时监控对数据的请求
SHUTDOWN SAVE #将数据安全的同步到磁盘后关闭redis-server

redis 发布与订阅功能(publish/subscribe)

# 频道: 消息队列
# SUBSCRIBE: 订阅一个或多个队列;
# PUBLISH: 向频道发布消息;
# UNSUBSCRIBE: 退订此前订阅的频道;
# PSUBSCRIBE: 模式订阅;
# term1 中开始一个频道; 
127.0.0.1:25612> SUBSCRIBE news
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "news"
3) (integer) 1

# term2 中向一个频道中发布消息;
127.0.0.1:25612> PUBLISH news "hello renjin"
(integer) 1

# term1 中可以收到消息;
1) "message"
2) "news"
3) "hello renjin"

# term1 中使用扩展模式开启两个频道;
127.0.0.1:25612> PSUBSCRIBE "rj.i[to]"
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "rj.i[to]"
3) (integer) 1

# term2 中向两个频道发布消息;
127.0.0.1:25612> PUBLISH rj.io "hello RenJin"
(integer) 1
127.0.0.1:25612> PUBLISH rj.it "hello SSJinYao"
(integer) 1

# term1 中可以收到两条消息;
1) "pmessage"
2) "rj.i[to]"
3) "rj.io"
4) "hello RenJin"
1) "pmessage"
2) "rj.i[to]"
3) "rj.it"
4) "hello SSJinYao"

Redis 的持久化:

# 提供了RDB和AOF两种机制;
    RDB: snapshot: 二进制格式; 按事先定制的策略,周期性地将数据保存至磁盘:数据文件默认为dump.rdb;
        客户端 也可以使用SAVE或BGSAVE命令启快照保存机制;
            SAVE:同步,在主线程中保存快照; 此时会阻塞所有客户端请求;
            BGSAVE: 异步,
    AOF:Aappend Only Fil
        记录每一次写操作至指定 的文件尾部实现持久化; 当redis重启时,可通过重新执行文件中的命令在内存重建数据库;
        BGREWRITEAOF: AOF文件重写:
            不会读取正在使用的AOF文件,而通过将内存中的数据以命令的方式保存到临时文件中,完之后替换原来的AOF文件;
    RDB:默认保存策略,取决于磁盘IO能力,与客户端对redis的读写;
        SAVE 900 1 
        SAVE 300 10
        SAVE 60 1000 
stop-writes-on-bgsave-error yes  # 在进行快照备份时,监控到持久化发现错误时,是否停止下来; 会报告一个访问错误;
rdbcompression yes # 是否采用压缩来节省使有空间,当然消耗cpu使用周期;
rdbchecksum yes  # 是否对rdb做校验码操作;
dbfilename dump.rdb # 指明文件名;
dir /var/lib/redis #指明保存文件的位置;
127.0.0.1:25612> CONFIG GET dir
1) "dir"
2) "/var/lib/redis"            

AOF:
    重写过程:
        (1) redis 主进程通过fork创建子进程;
        (2) 子进程根据redis内存中的数据创建数据库重建命令序列于临时文件中;
        (3) 父进程继承client的请求时,并会把这些请求中的写操作继续追加至原来的AOF文件;
            额外地,这些新的写请求还会被放置于一个缓冲队列中;
        (4) 子进程重写完成,会通知父进程,父进程把缓冲中的命令写到临时文件中;
        (5) 父进程用临时文件替换老的aof文件;

        appenonly no #没有开启AOF 功能;
        appendfilename "appendonly.aof" # 文件名
        appendfsync eversec  # 每秒中写一次
        no-appedfsync-no-rewrite no #  对新的操作不做fsync,而是放在缓存队列中的;
        auto-aof-rewrite-percentage 100 # 当前afo 文件是上次的两倍时,再重新触发重写操作;
                auto-aof-rewrite-min-size 64mb # 
127.0.0.1:25612> CONFIG SET appendonly yes
OK

# 注意: 持久本身不能取代备份: 还应该制定备份策略,对redis数据库进行定期备份;
# RDB与AOF同时启用:
    (1) BGSAVE和BGREWRITEAOF 不会同是执行;
    (2) 在Redis服务器启用于恢复数据时,会优先使用AOF;

Redis复制:

特点:
    一个Master 可以有多个Slave;
    支持链式复制;
        Master以非阻塞方式同步数据至slave; 注:主服务器不建议关闭持久化;
slave:
    > SLAVEOF MASTER_IP MASTER_PORT
    min-salves-to-write 3  # 至少应该有三个从节点,小于三个,禁止主服务器写操作;
    min-salves-max-lag # 从服务器必需不能滞后于服务器10秒以上;
注意: 如果master使用requirespass开启了认证功能,从服务器要使用masterauth <PASSWORD>;
    来连入服务请求使用此密码进行认证;

sentinal: 万一主服务器岩了,那么它会从从服务器节点中选则一台服务器成为主节点;
    万sentinal 故障,或者连接不上主节点时,需要sentinal配置多个节点;

sentinel:

用于管理多个redis服务实现HA;
    监控;
    通知;
    自动故障转移;
    本质上,sentinel也是redis的分布式功能;
    使用流言协议、投票协议;
程序:
    redis-sentinel /path/to/file.conf
    redis-server /path/to/file.conf
(1) 服务器自身初始化,运行redis-server中专用于sentinel功能的代码;
(2) 初始化sentinel状态,根据给定的配置文件,初始化监控的master服务器列表;
(3) 创建连向master的连接;
专用配置文件: /etc/redis-sentinel.conf
(1) # sentinel monitor <master-name> <ip> <redis-port> <quorum>
    sentinel monitor mymaster  127.0.0.1 6379 2
(2) # sentinel down-after-millisenconds <master-name> <millisends>
    sentinel down-afer-millisenconds mymaster 3000
(3) # sentinel parellel-syncs  <master-name> <numslaves>
    seninel parallel-syncs mymaster 1 
(4) # sentinel failover-timeout <master-name> <milliseconds>
    sentinel failover-timeout mymaster 180000

主观下线,客观下线:
    主观下线: 一个sentinel实例判断出某节点下线:
    客观下线:多个seninel 节点协商后判断出某节点下线:

专用命令:
    SENTINEL masters
    SENTINEL slaves <master name>
    SENTINEL get-master-addr-by-name <master name>
    SENTINEL reset
    SENTINEL failover <master name>

Clustering:
    分布式数据库,通过分片机制进行数据分布,clustering内的每个子节点仅数据库的一部分数据;

评论