zoukankan      html  css  js  c++  java
  • redis

    redis 持久化功能
    1、RDB
    RDB是基于快照的一种持久化功能,保存某个时间点的,key:value状态。
    dbfilename dump.rdb
    dir /data/redis
    save 900 1
    save 300 10
    save 60 10000
    优点:
    快速持久化,
    占用磁盘空间少,
    一般备份是通过RDB实现的,
    主从复制功能也是通RDB功能实现的。

    缺点:
    当断电,重启时,RDB会丢失少部分数据。


    2、AOF
    appendonly LogFile,追加模式的日志记录持久化方式。会记录redis中所有变更类的命令。

    appendonly yes
    appendfsync always
    appendfsync everysec


    优点:相对RDB来讲,更加安全了。
    缺点:持久化速度相对较慢,需要更多的存储空间。


    数据类型:
    string
    hash
    list
    set
    sorted set

    key:value
    -----------------
    key的通用操作:

    KEYS * 查看KEY支持通配符
    DEL 删除给定的一个或多个key
    EXISTS 检查是否存在
    RENAME 变更KEY名
    TYPE 返回键所存储值的类型
    EXPIRE PEXPIRE 以秒毫秒设定生存时间
    TTL PTTL 以秒毫秒为单位返回生存时间
    PERSIST 取消生存实现设置

    --------------------
    STRING

    计数器的实现:

    incr num 每次累计加1
    decr num 每次累计减1

    incrby num 10000 累计加10000
    decrby num 10000 累计减10000

    普通键值对操作:

    127.0.0.1:6379> set name zhangsan
    OK
    127.0.0.1:6379>
    127.0.0.1:6379>
    127.0.0.1:6379> get name
    "zhangsan"
    127.0.0.1:6379> mset id 101 name zhangsan age 20 gender m
    OK
    127.0.0.1:6379> keys *
    1) "name"
    2) "id"
    3) "xyz"
    4) "jishu"
    5) "age"
    6) "gender"
    127.0.0.1:6379> mget id name age gender
    1) "101"


    set mykey "test" 为键设置新值,并覆盖原有值
    getset mycounter 0 设置值,取值同时进行
    setex mykey 10 "hello" 设置指定 Key 的过期时间为10秒,在存活时间可以获取value
    setnx mykey "hello" 若该键不存在,则为键设置新值
    mset key3 "zyx" key4 "xyz" 批量设置键


    del mykey 删除已有键


    append mykey "hello" 若该键并不存在,返回当前 Value 的长度
    该键已经存在,返回追加后 Value的长度
    incr mykey 值增加1,若该key不存在,创建key,初始值设为0,增加后结果为1
    decrby mykey 5 值减少5
    setrange mykey 20 dd 把第21和22个字节,替换为dd, 超过value长度,自动补0


    exists mykey 判断该键是否存在,存在返回 1,否则返回0
    get mykey 获取Key对应的value
    strlen mykey 获取指定 Key 的字符长度
    ttl mykey 查看一下指定 Key 的剩余存活时间(秒数)
    getrange mykey 1 20 获取第2到第20个字节,若20超过value长度,则截取第2个和后面所有的
    mget key3 key4 批量获取键

    ---------------------------------
    Hash类型(字典)

    hmset stu id 101 name zhangsan age 20 gender m
    hgetall stu
    hmget stu id name
    HVALS stu



    hset myhash field1 "s"
    若字段field1不存在,创建该键及与其关联的Hashes, Hashes中,key为field1 ,并设value为s ,若存在会覆盖原value
    hsetnx myhash field1 s
    若字段field1不存在,创建该键及与其关联的Hashes, Hashes中,key为field1 ,并设value为s, 若字段field1存在,则无效
    hmset myhash field1 "hello" field2 "world 一次性设置多个字段

    hdel myhash field1 删除 myhash 键中字段名为 field1 的字段
    del myhash 删除键

    hincrby myhash field 1 给field的值加1

    hget myhash field1 获取键值为 myhash,字段为 field1 的值
    hlen myhash 获取myhash键的字段数量
    hexists myhash field1 判断 myhash 键中是否存在字段名为 field1 的字段
    hmget myhash field1 field2 field3 一次性获取多个字段
    hgetall myhash 返回 myhash 键的所有字段及其值
    hkeys myhash 获取myhash 键中所有字段的名字
    hvals myhash 获取 myhash 键中所有字段的值

    -----------------
    List 列表

    127.0.0.1:6379> lpush wechat "today is nice day!"
    (integer) 1
    127.0.0.1:6379> lpush wechat "today is bad day!"
    (integer) 2
    127.0.0.1:6379> lpush wechat "today is good day!"
    (integer) 3
    127.0.0.1:6379> lpush wechat "today is abc day!"
    (integer) 4
    127.0.0.1:6379> lpush wechat "today is xyz day!"
    127.0.0.1:6379> LRANGE wechat 0 -1
    1) "today is xyz day!"
    2) "today is abc day!"
    3) "today is good day!"
    4) "today is bad day!"
    5) "today is nice day!"
    127.0.0.1:6379> LRANGE wechat -1 -2
    (empty list or set)
    127.0.0.1:6379> LRANGE wechat -2 -3
    (empty list or set)
    127.0.0.1:6379> LRANGE wechat -2 -1
    1) "today is bad day!"
    2) "today is nice day!"
    127.0.0.1:6379> LRANGE wechat -2 -2
    1) "today is bad day!"
    127.0.0.1:6379>
    127.0.0.1:6379> LINDEX wechat 2
    "today is bad day!"
    127.0.0.1:6379>
    127.0.0.1:6379> LPOP wechat
    "today is xyz day!"



    lpush mykey a b 若key不存在,创建该键及与其关联的List,依次插入a ,b, 若List类型的key存在,则插入value中
    lpushx mykey2 e 若key不存在,此命令无效, 若key存在,则插入value中
    linsert mykey before a a1 在 a 的前面插入新元素 a1
    linsert mykey after e e2 在e 的后面插入新元素 e2
    rpush mykey a b 在链表尾部先插入b,在插入a
    rpushx mykey e 若key存在,在尾部插入e, 若key不存在,则无效
    rpoplpush mykey mykey2 将mykey的尾部元素弹出,再插入到mykey2 的头部(原子性的操作)

    del mykey 删除已有键
    lrem mykey 2 a 从头部开始找,按先后顺序,值为a的元素,删除数量为2个,若存在第3个,则不删除
    ltrim mykey 0 2 从头开始,索引为0,1,2的3个元素,其余全部删除

    lset mykey 1 e 从头开始, 将索引为1的元素值,设置为新值 e,若索引越界,则返回错误信息
    rpoplpush mykey mykey 将 mykey 中的尾部元素移到其头部

    lrange mykey 0 -1 取链表中的全部元素,其中0表示第一个元素,-1表示最后一个元素。
    lrange mykey 0 2 从头开始,取索引为0,1,2的元素
    lrange mykey 0 0 从头开始,取第一个元素,从第0个开始,到第0个结束
    lpop mykey 获取头部元素,并且弹出头部元素,出栈
    lindex mykey 6 从头开始,获取索引为6的元素 若下标越界,则返回nil

    -----------------------
    set 集合

    127.0.0.1:6379> sadd lxl jnl pg ms mr abc xyz baoqiang yf
    (integer) 8
    127.0.0.1:6379> sadd jnl baoqiang yf xyz mr lxl
    (integer) 5
    127.0.0.1:6379> SINTER lxl jnl
    1) "mr"
    2) "baoqiang"
    3) "xyz"
    4) "yf"
    127.0.0.1:6379> SDIFF lxl jnl
    1) "jnl"
    2) "abc"
    3) "ms"
    4) "pg"
    127.0.0.1:6379> SDIFF jnl lxl
    1) "lxl"
    127.0.0.1:6379>
    127.0.0.1:6379>
    127.0.0.1:6379>
    127.0.0.1:6379> SUNION jnl lxl
    1) "baoqiang"
    2) "pg"
    3) "xyz"
    4) "yf"
    5) "lxl"
    6) "mr"
    7) "jnl"
    8) "ms"
    9) "abc"

    127.0.0.1:6379> SINTERSTORE gthy lxl jnl
    (integer) 4
    127.0.0.1:6379> SMEMBERS gthy
    1) "mr"
    2) "baoqiang"
    3) "yf"
    4) "xyz"
    127.0.0.1:6379>

    ------
    有序集合

    ---------

    发布订阅:

    窗口1:
    redis-cli -a 123

    SUBSCRIBE fm1039 订阅单个频道
    PSUBSCRIBE fm* 订阅多个频道

    窗口2:

    127.0.0.1:6379> PUBLISH fm1039 "hi!"
    (integer) 1

    127.0.0.1:6379> PUBLISH fm1039 "hi!"
    (integer) 1
    127.0.0.1:6379> PUBLISH fm1038 "hi!"
    (integer) 1
    127.0.0.1:6379> PUBLISH fm1037 "hi!"
    (integer) 1
    127.0.0.1:6379>
    --------------------------------------------------------
    vim Linux文本编辑工具

    1、命令模式:

    G 光标到达最后一行
    10G 光标到到10行
    3yy 复制3行
    3dd 删除(剪切)
    p 粘贴
    dG 删除所有行
    u 撤销到上次操作
    ^ 光标到达行首
    $ 光标到达行尾
    / 查找关键字

    2、编辑模式(插入模式)
    a i o

    3、末行模式(冒号模式)
    :wq


    ---------------------------------------------------------
    主从复制实现:


    1、环境:
    准备两个或两个以上redis实例

    mkdir /data/638{0..2}

    配置文件示例:
    vim /data/6380/redis.conf
    port 6380
    daemonize yes
    pidfile /data/6380/redis.pid
    loglevel notice
    logfile "/data/6380/redis.log"
    dbfilename dump.rdb
    dir /data/6380
    protected-mode no


    vim /data/6381/redis.conf
    port 6381
    daemonize yes
    pidfile /data/6381/redis.pid
    loglevel notice
    logfile "/data/6381/redis.log"
    dbfilename dump.rdb
    dir /data/6381
    protected-mode no


    vim /data/6382/redis.conf
    port 6382
    daemonize yes
    pidfile /data/6382/redis.pid
    loglevel notice
    logfile "/data/6382/redis.log"
    dbfilename dump.rdb
    dir /data/6382
    protected-mode no

    启动:
    redis-server /data/6380/redis.conf
    redis-server /data/6381/redis.conf
    redis-server /data/6382/redis.conf


    主节点:6380
    从节点:6381、6382


    2、开启主从:
    6381/6382命令行:

    redis-cli -p 6381
    SLAVEOF 127.0.0.1 6380

    redis-cli -p 6382
    SLAVEOF 127.0.0.1 6380


    3、查询主从状态

    从库:
    [root@db01 ~]# redis-cli -p 6382

    127.0.0.1:6382> info replication

    [root@db01 ~]# redis-cli -p 6381
    127.0.0.1:6381> info replication

    -----
    redis-sentinel(哨兵)

    1、监控
    2、自动选主,切换(6381 slaveof no one)
    3、2号从库(6382)指向新主库(6381)
    -------------
    sentinel搭建过程

    mkdir /data/26380
    cd /data/26380

    vim sentinel.conf
    port 26380
    dir "/data/26380"
    sentinel monitor mymaster 127.0.0.1 6380 1
    sentinel down-after-milliseconds mymaster 5000

    启动:
    redis-sentinel /data/26380/sentinel.conf &
    --------------------------------
    windows安装redis新驱动

    cd d:
    d:
    D:>cd redis
    D: edis>python3 setup.py install

    sentinel模式:

    >>> from redis.sentinel import Sentinel
    >>> sentinel = Sentinel([('127.0.0.1', 26379)], socket_timeout=0.1)
    >>> sentinel.discover_master('mymaster')
    >>> sentinel.discover_slaves('mymaster')
    >>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
    >>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
    >>> master.set('foo', 'bar')
    >>> slave.get('foo')
    'bar'

    ---------------------------------
    redis cluster

    高性能:


    1、在多分片节点中,将16384个槽位,均匀分布到多个分片节点中
    2、存数据时,将key做crc16(key),然后和16384进行取模,得出槽位值(0-16383之间)
    3、根据计算得出的槽位值,找到相对应的分片节点的主节点,存储到相应槽位上
    4、如果客户端当时连接的节点不是将来要存储的分片节点,分片集群会将客户端连接切换至真正存储节点进行数据存储

    高可用:
    在搭建集群时,会为每一个分片的主节点,对应一个从节点,实现slaveof的功能,同时当主节点down,实现类似于sentinel的自动failover的功能。

    规划、搭建过程:

    6个redis实例,一般会放到3台硬件服务器
    注:在企业规划中,一个分片的两个分到不同的物理机,防止硬件主机宕机造成的整个分片数据丢失。

    端口号:7000-7005

    1、安装集群插件
    EPEL源安装ruby支持
    yum install ruby rubygems -y

    使用国内源
    gem sources -l
    gem sources -a http://mirrors.aliyun.com/rubygems/
    gem sources --remove http://rubygems.org/
    gem install redis -v 3.3.3
    gem sources -l

    或者:
    gem sources -a http://mirrors.aliyun.com/rubygems/ --remove http://rubygems.org/

    ---
    2、集群节点准备

    mkdir /data/700{0..5}

    vim /data/7000/redis.conf
    port 7000
    daemonize yes
    pidfile /data/7000/redis.pid
    loglevel notice
    logfile "/data/7000/redis.log"
    dbfilename dump.rdb
    dir /data/7000
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes


    vim /data/7001/redis.conf
    port 7001
    daemonize yes
    pidfile /data/7001/redis.pid
    loglevel notice
    logfile "/data/7001/redis.log"
    dbfilename dump.rdb
    dir /data/7001
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes


    vim /data/7002/redis.conf
    port 7002
    daemonize yes
    pidfile /data/7002/redis.pid
    loglevel notice
    logfile "/data/7002/redis.log"
    dbfilename dump.rdb
    dir /data/7002
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes

    vim /data/7003/redis.conf
    port 7003
    daemonize yes
    pidfile /data/7003/redis.pid
    loglevel notice
    logfile "/data/7003/redis.log"
    dbfilename dump.rdb
    dir /data/7003
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes

    vim /data/7004/redis.conf
    port 7004
    daemonize yes
    pidfile /data/7004/redis.pid
    loglevel notice
    logfile "/data/7004/redis.log"
    dbfilename dump.rdb
    dir /data/7004
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes


    vim /data/7005/redis.conf
    port 7005
    daemonize yes
    pidfile /data/7005/redis.pid
    loglevel notice
    logfile "/data/7005/redis.log"
    dbfilename dump.rdb
    dir /data/7005
    protected-mode no
    cluster-enabled yes
    cluster-config-file nodes.conf
    cluster-node-timeout 5000
    appendonly yes


    启动节点:

    redis-server /data/7000/redis.conf
    redis-server /data/7001/redis.conf
    redis-server /data/7002/redis.conf
    redis-server /data/7003/redis.conf
    redis-server /data/7004/redis.conf
    redis-server /data/7005/redis.conf

    [root@db01 ~]# ps -ef |grep redis
    root 8854 1 0 03:56 ? 00:00:00 redis-server *:7000 [cluster]
    root 8858 1 0 03:56 ? 00:00:00 redis-server *:7001 [cluster]
    root 8860 1 0 03:56 ? 00:00:00 redis-server *:7002 [cluster]
    root 8864 1 0 03:56 ? 00:00:00 redis-server *:7003 [cluster]
    root 8866 1 0 03:56 ? 00:00:00 redis-server *:7004 [cluster]
    root 8874 1 0 03:56 ? 00:00:00 redis-server *:7005 [cluster]


    3、将节点加入集群管理

    redis-trib.rb create --replicas 1 127.0.0.1:7000 127.0.0.1:7001
    127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005

    ---------------------


    redis的多API支持


    python为例

    tar xf Python-3.5.2.tar.xz
    cd Python-3.5.2
    ./configure
    make && make install

    https://redis.io/clients

    下载redis-py-master.zip
    unzip redis-py-master.zip
    cd redis-py-master

    python3 setup.py install


    安装redis-cluser的客户端程序
    cd redis-py-cluster-unstable
    python3 setup.py install

    1、对redis的单实例进行连接操作

    python3
    >>>import redis
    >>>r = redis.StrictRedis(host='localhost', port=6379, db=0,password='123')
    >>>r.set('foo', 'bar')
    True
    >>>r.get('foo')
    'bar'


    --------------------

    2、sentinel集群连接并操作


    [root@db01 ~]# redis-server /data/6380/redis.conf
    [root@db01 ~]# redis-server /data/6381/redis.conf
    [root@db01 ~]# redis-server /data/6382/redis.conf
    [root@db01 ~]# redis-sentinel /data/26380/sentinel.conf &

    --------------------------------
    ## 导入redis sentinel包
    >>> from redis.sentinel import Sentinel
    ##指定sentinel的地址和端口号
    >>> sentinel = Sentinel([('localhost', 26380)], socket_timeout=0.1)
    ##测试,获取以下主库和从库的信息
    >>> sentinel.discover_master('mymaster')
    >>> sentinel.discover_slaves('mymaster')
    ##配置读写分离
    #写节点
    >>> master = sentinel.master_for('mymaster', socket_timeout=0.1)
    #读节点
    >>> slave = sentinel.slave_for('mymaster', socket_timeout=0.1)
    ###读写分离测试 key
    >>> master.set('oldboy', '123')
    >>> slave.get('oldboy')
    '123'


    ----------------------
    redis cluster的连接并操作(python2.7.2以上版本才支持redis cluster,我们选择的是3.5)
    https://github.com/Grokzen/redis-py-cluster


    3、python连接rediscluster集群测试
    使用

    python3
    >>> from rediscluster import StrictRedisCluster
    >>> startup_nodes = [{"host": "127.0.0.1", "port": "7000"}]
    ### Note: decode_responses must be set to True when used with python3
    >>> rc = StrictRedisCluster(startup_nodes=startup_nodes, decode_responses=True)
    >>> rc.set("foo", "bar")
    True
    >>> print(rc.get("foo"))
    'bar'
    ----------------------

  • 相关阅读:
    Base64 加密之中文乱码
    JAVA 笔记 ReadWriteLock
    手机上的消息推送
    Erlang 聊天室程序(九) 主题房间2 房间信息管理
    阿里云服务器上安装GCC
    jq实现窗帘式图片
    Oracle版本问题!【急急急】
    解决 VSCode git commit 时 No such file or directory 报错问题
    GIT Authentication failed for错误问题处理
    h5接入微信分享sdk,报错Cannot read property of undefined (reading 'title')
  • 原文地址:https://www.cnblogs.com/maojiang/p/9396061.html
Copyright © 2011-2022 走看看