redis

redis

1.查看配置文件、命令工具

  1. ​ cd /usr/local/bin
    • redis-server redis 服务器
    • redis-cli redis 命令行客户端
    • redis-benchmakr 性能测试工具
    • redis-check-aof AOF文件修复工具
    • redis-check-rdb RDB文件检索工具
  2. sudo vim /etc/redis/redis.conf 查看配置
  3. dir /var/lib/redis 数据文件储存路径
  4. logfile “/var/log/redis/redis-server.log” 日志文件
  5. 个人习惯
    • ps aux |grep redis 查看进程
    • sudo kill -9 pid 杀死进程
    • sudo redis-server /etc/redis/…conf 指定加载配置文件
    • select 10 切换数据库

2.string类型

(1)增
  1. ​ set key value 设置键值
  2. ​ setex key seconds value 设置键值及过期时间,以秒为单位
  3. mset key1 value1 key2 value2 … 设置多个键值
  4. incr 计数加1
  5. decr 计数减1
  6. incrby 计数加n
(2)获取

​ 1 get key

​ 2 mget key

(3)健命令
  1. ​ keys * 查看所有键
  2. keys a* 查看名称中包含a的健
  3. exists key1 判断键是否存在,如果存在返回1,不存在返回0
  4. ​ type key 查看键对应的value的类型
  5. del key1 key2 … 删除键及对应值
  6. expire key seconds 设置过期时间,以秒为单位
  7. ttl key 查看有效时间,以秒为单位

3.hash类型

(1)增、修
  1. ​ hset key field value 设置单个属性
  2. hset key field1 value1 filed2 value2 … 设置多个属性
(2)获取
  1. ​ hget key field 获取⼀个属性的值
  2. hmget key field1 field2 … 获取多个属性的值
(3)删除
  • 删除整个hash键及值,使⽤del命令
  1. ​ hdel key field1 field2 … 删除属性,属性对应的值会被⼀起删除

4.list类型

(1)增加
  • lpush key value1 value2 …在左侧插⼊数据
  • rpush key value1 value2 …在右侧插⼊数据
  • linsert key before 或after b a 在指定元素的前或后插⼊新元素
  • lset 从左修改元素
(2)获取
  • ​ lrange key start stop 返回列表⾥指定范围内的元素
    • startstop为元素的下标索引
    • 索引从左侧开始,第⼀个元素为0
    • 索引可以是负数,表示从尾部开始计数,如-1表示最后⼀个元素
  • lset key index value 设置指定索引位置的元素值
(3)删除
  • ​ lrem key count value 删除指定元素
    • 将列表中前count次出现的值为value的元素移除
    • count > 0: 从头往尾移除
    • count < 0: 从尾往头移除
    • count = 0: 移除所有
  • ltrim key start stop 修剪(截取) 在[start stop]区间内的元素,区间外的元素全部删除
  • lpop 从左删除元素
  • rpop 从右删除元素

5.set类型

  • sadd key member1 member2 … 添加元素
  • smembers key 返回所有元素
  • srem key 删除指定元素

6.zset类型

  • zadd key score1 member1 score2 member2 … 添加

    • sorted set,有序集合
    • 元素为string类型
    • 元素具有唯⼀性,不重复
    • 每个元素都会关联⼀个double类型的score,表示权重,通过权重将元素从⼩到⼤排序
    • 说明:没有修改操作
    1. zrange key start stop 返回指定范围索引
    2. zrevrange 反向变立元素
    3. zrangebyscore key min max 返回score值在minmax之间的成员
    4. zscore key member 返回成员memberscore
    • zrem key member1 member2 … 删除指定元素
    • zremrangebyscore key min max 删除权重在指定范围的元素

    7.redis-py的使用

    from redis import StrictRedis
    
    # 创建redis实例对象  redis默认会对数据进行utf-8编码
    redis_client = StrictRedis(host='127.0.0.1', port=6379, db=0, decode_responses=True)
    
    # 操作语法和官方命令一样
    redis_client.set('name', 'zs', ex=10)
    print(redis_client.get('name'))
    
    # 多值操作
    redis_client.hmset('user:1', {'name': 'zs', 'age': 20})
    print(redis_client.hmget('user:1', ['name', 'age']))

    8.redis事务

    基本语法
    • multi
      • 开启事务, 后续的命令会被加入到同一个事务中
      • 事务中的操作会发给服务端, 但是不会立即执行, 而是放到了该事务的对应的一个队列中, 服务端返回QUEUED
    • exec
      • 执行EXEC后, 事务中的命令才会被执行
      • 事务中的命令出现错误时, 不会回滚也不会停止事务, 而是继续执行
    • discard
      • 取消事务, 事务队列会清空, 客户端退出事务状态
    ACID
    • 原子性
      • 不支持
      • 不会回滚并且继续执行
    • 隔离性
      • 支持
      • 事务中命令顺序执行, 并且不会被其他客户端打断 (先EXEC的先执行)
      • 单机redis读写操作使用 单进程单线程
    • 持久性
      • 支持, 但相比Mysql, redis数据易丢失
    • 一致性
      • 不支持
    from redis import StrictRedis
    
    # 创建redis客户端
    redis_client = StrictRedis()
    
    # 创建管道对象  默认会开启事务
    pipe = redis_client.pipeline()
    
    # pipe的后续操作会被放入事务中  不会立即执行
    a = pipe.set('name', 'zhangsan')
    b = pipe.get('name')
    
    # 提交事务   提交才会执行事务中的命令
    c = pipe.execute()
    
    print(a)
    print(b)
    print(c)

    注意点:

    • 创建管道后, 默认会开启事务
    • 放入事务中的命令在执行 execute方法后才会执行

    9.redis乐观锁

    基本语法
    • watch
      • redis实现的乐观锁
    • 机制
      • 事务开启前, 设置对数据的监听, EXEC时, 如果发现数据发生过修改, 事务会自动取消(DISCARD)
      • 事务EXEC后, 无论成败, 监听会被移除
    watch mykey  #设置监视值
    multi	#开启事务
    set mykey 10	
    exec	#如果mykey的值在执行exec之前发生过改变, 则该事务会取消(客户端可以在发生碰撞后不断重试)
    

    应用场景

    • 避免并发引起的资源抢夺问题
    # 需求: 使用redis实现秒杀功能 (防止超卖)
    from redis import StrictRedis, WatchError
    
    # 1.创建客户端对象
    redis_cli = StrictRedis(decode_responses=True)
    # 2.创建管道对象
    pipeline = redis_cli.pipeline()
    
    # 监听的key
    key = "count"
    
    while True:
        # 3.使用watch命令监视键值对数据
        pipeline.watch(key)
    
        # 4.获取库存
        count = redis_cli.get(key)
        try:
            if int(count) > 0:
                # 5.手动开启事务
                # 注意:使用了watch命令,管道对象就不会自动开启事务,需要手动开启
                pipeline.multi()
                # 6.在事务内部修改数据【减库存】
                pipeline.decr(key)
                # 7.提交事务
                pipeline.execute()
                print("下单成功")
            else:
                print("库存不足")
                # 移除监视
                pipeline.reset()
            break
        except WatchError as e:
            print("库存不足: {}".format(e))
            continue

10.redis悲观锁

基本语法
  • SETNX命令
    • 键不存在才会设置成功
    • 多个客户端抢夺, 只有一个可以设置成功(获取锁, 获取操作数据的权限)
setnx lock1 1    # 键不存在,才会设置成功
1
setnx lock1 1	 # 键存在, 无法设置, 返回0
0
# 需求:使用redis悲观锁解决超卖问题
from redis import StrictRedis

# 1.创建redis客户端对象
redis_cli = StrictRedis(decode_responses=True)

# 2.设置锁的键
key = "user:lock"

while True:
    # 3.争夺锁资源
    lock = redis_cli.setnx(key, 66)

    if lock:
        # 给锁设置有效期,防止忘记移除锁资源,出现死锁
        redis_cli.expire(key, 5)

        # 4.获取库存
        count = redis_cli.get("count")
        if int(count) > 0:
            # 5.修改库存
            redis_cli.decr("count")
            print("下单成功")
        else:
            print("库存不足")
        # 6.移除锁资源
        redis_cli.delete(key)
        break

11.非事务性管道

  • redis的事务和管道可以分离, 可以 不使用事务的情况下单独使用管道
  • 管道可以实现 一次发送多条命令给redis服务器, 提高传输效率
from redis import StrictRedis

# 1.创建redis客户端对象
# decode_responses=True 将bytes类型转换成string
redis_cli = StrictRedis(decode_responses=True)

# 2.创建非事务性管道: transaction=False
pipeline = redis_cli.pipeline(transaction=False)

# 3.往管道中添加命令'
a = pipeline.set("user6", "zs")
b = pipeline.get("user6")

# 4.执行管道中的命令
ret = pipeline.execute()

print(a)
print(b)
print(ret)

redis分布式

1.数据库主从

基本介绍
  • 作用
    • 数据备份
    • 读写分离
  • 特点
    • 只能一主多从 (mysql可以多主多从)
    • 从数据库不能写入 (mysql可以写)
配置主
  • 查看当前主机的ip地址

  • 修改etc/redis/redis.conf文件

    sudo vi redis.conf
    bind 192.168.26.128

  • 重启redis服务

    sudo service redis stop
    redis-server redis.conf

配置从
  • 复制etc/redis/redis.conf文件

    sudo cp redis.conf ./slave.conf

  • 修改redis/slave.conf文件

    sudo vi slave.conf

  • 编辑内容

    bind 192.168.26.128
    slaveof 192.168.26.128 6379
    port 6378

  • redis服务

    sudo redis-server slave.conf

  • 查看主从关系

    redis-cli -h 192.168.26.128 info Replication

2.哨兵模式

1. 基本介绍
  • 作用
    • 监控redis服务器的运行状态, 可以进行 自动故障转移(failover), 实现高可用
    • 数据库主从 配合使用的机制
  • 特点
    • 独立的进程, 每台redis服务器应该至少配置一个哨兵程序
    • 监控redis主服务器的运行状态
    • 出现故障后可以向管理员/其他程序发出通知
    • 针对故障,可以进行自动转移, 并向客户端提供新的访问地址
内部机制 (了解)
  • 流言协议
    • 当某个哨兵程序ping 发现监视的主服务器下线后(心跳检测), 会向监听该服务器的其他哨兵询问, 是否确认主服务器下线, 当 确认的哨兵数量 达到要求(配置文件中设置)后, 会确认主服务器下线(客观下线), 然后进入投票环节
  • 投票协议
    • 当确认主服务器客观下线后, 哨兵会通过 投票的方式 来授权其中一个哨兵主导故障转移处理
    • 只有在 大多数哨兵都参加投票 的前提下, 才会进行授权, 比如有5个哨兵, 则需要至少3个哨兵投票才可能授权
    • 目的是避免出现错误的故障迁移
  • 建议最低配置
    • 至少在3台服务器上分别启动至少一个哨兵
    • 如果只有一台, 则服务器宕机后, 将无法进行故障迁移
    • 如果只有两台, 一旦一个哨兵挂掉了, 则投票会失败
2. 相关配置
  • 哨兵模式是Redis官方自带的工具, 默认安装
  • 哨兵模式的配置模板在Redis的安装包中, 默认名为 sentinel.conf
# 在/etc/redis中创建三个配置文件
# sentinel_26380.conf
port 26380  
sentinel monitor mymaster 127.0.0.1 6381 2  
sentinel down-after-milliseconds mymaster 30000  
daemonize yes 
logfile "/var/log/redis-sentinel-26380.log"
  
  • 启动哨兵模式
sudo redis-sentinel sentinel.conf
from redis.sentinel import Sentinel, StrictRedis

# 1.构建哨兵连接信息
SENTINEL_HOSTS = [
    ("192.168.243.157", 26380),
    ("192.168.243.157", 26381),
    ("192.168.243.157", 26382),
]

# 2.创建哨兵客户端对象
sentinel = Sentinel(SENTINEL_HOSTS)

# 3.准备哨兵监视的主服务器别名
# 注意:需要和配置文件中监视的主服务器别名保持一致
master_name = 'mymaster'

# 4.根据监视的服务器别名获取主、从的redis客户端对象
# 主库
master = sentinel.master_for(master_name, decode_responses=True)
# 从库
slave = sentinel.slave_for(master_name, decode_responses=True)
# 写
master.set("name", "curry1")
# 读取
print(slave.get("name"))

3.集群

1. 基本介绍
  • 多个节点共同保存数据
  • 作用
    • 扩展存储空间
    • 提高吞吐量, 提高写的性能
  • 和单机的不同点
    • 不再区分数据库, 只有0号库, 单机默认0-15
    • 不支持事务/管道/多值操作
  • 特点
    • 要求至少 三主三从
    • 要求必须开启 AOF持久化
    • 自动选择集群节点进行存储
    • 默认集成哨兵, 自动故障转移
2. 相关配置
  • 在前边课程中已经讲解过Redis集群的配置, 此处以回顾为主
# 每个节点分别配置ip/端口, 注释表示接受所有请求
# bind 127.0.0.1
port 6379
# 集群配置
cluster-enabled yes   # 开启集群
cluster-config-file nodes-7000.conf  # 节点日志文件
cluster-node-timeout 15000  # 节点超时时长 15秒
# 开启AOF 及相关配置  
appendonly yes
创建集群
  • CentOS虚拟机中已经配置好了6个集群节点(三主三从)的配置文件, 存放在 /etc/redis 目录下, 分别是 7000.conf7005.conf 6个文件

  • redis-trib.rb create --replicas 1 192.168.105.140:7000 192.168.105.140:7001 192.168.105.140:7002 192.168.105.140:7003 192.168.105.140:7004 192.168.105.140:7005
from rediscluster import RedisCluster

# 带卡槽的数据库连接信息
startup_nodes = [
    {"host": "192.168.243.157", "port": 7000},
    {"host": "192.168.243.157", "port": 7001},
    {"host": "192.168.243.157", "port": 7002},
]

# 方案1:通过带卡槽的redis数据库对象,启动集群
# 1.创建集群的客户端对象
cluster = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)

# 方案2:蔓延机制,根据任意一个ip和端口能够获取集群所有的节点
# cluster = RedisCluster(host="192.168.243.157", port=7005, decode_responses=True)

# 2.设置值
cluster.set("user777", "curry")
print(cluster.get("user777"))

redis持久化

redis可以将数据写入到磁盘中,在停机或宕机后,再次启动redis时,将磁盘中的备份数据加载到内存中恢复使用。这是redis的持久化。持久化有如下两种机制。

RDB 快照持久化

redis可以将内存中的数据写入磁盘进行持久化。在进行持久化时,redis会创建子进程来执行。

redis默认开启了快照持久化机制。

进行快照持久化的时机如下

  • 定期触发

    redis的配置文件

      #   save  
      #
      #   Will save the DB if both the given number of seconds and the given
      #   number of write operations against the DB occurred.
      #
      #   In the example below the behaviour will be to save:
      #   after 900 sec (15 min) if at least 1 key changed
      #   after 300 sec (5 min) if at least 10 keys changed
      #   after 60 sec if at least 10000 keys changed
      #
      #   Note: you can disable saving completely by commenting out all "save" lines.
      #
      #   It is also possible to remove all the previously configured save
      #   points by adding a save directive with a single empty string argument
      #   like in the following example:
      #
      #   save ""
    
      save 900 1
      save 300 10
      save 60 10000
  • BGSAVE

    执行BGSAVE命令,手动触发RDB持久化

  • SHUTDOWN

    关闭redis时触发

AOF 追加文件持久化

redis可以将执行的所有指令追加记录到文件中持久化存储,这是redis的另一种持久化机制。

redis默认未开启AOF机制。

redis可以通过配置如下项开启AOF机制

appendonly yes  # 是否开启AOF
appendfilename "appendonly.aof"  # AOF文件

AOF机制记录操作的时机

# appendfsync always  # 每个操作都写到磁盘中
appendfsync everysec  # 每秒写一次磁盘,默认
# appendfsync no  # 由操作系统决定写入磁盘的时机

使用AOF机制的缺点是随着时间的流逝,AOF文件会变得很大。但redis可以压缩AOF文件。

结合使用

redis允许我们同时使用两种机制,通常情况下我们会设置AOF机制为everysec 每秒写入,则最坏仅会丢失一秒内的数据。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值