Redis内容

Redis简介

数据库分两类

  • 关系型数据库: 数据以虚拟表格的形式存储! mysql,sqlite,oracle,sqlserver,postgresql等...
  • 非关系型/面向对象数据库/缓存数据库: 存储的key:value字符串! redis,mongdb,memcache
    • 使用最多: redis
    • 数据存储在内存中!

特点

  1. 以字典结构存储数据
  2. 允许通过TCP协议读取字典的内容
  3. 强大的缓存系统, 可以为每个键设置TTL, 以及按照一定规则自动淘汰不需要的键
  4. 支持使用列表的形式构造任务队列
  5. 数据存储在内存中也可以持久化到硬盘
    重点: 存储字符串类型, 是键值对!

安装

  • window
    解压后直接使用
  1. 启动服务端 redis-server.exe 2. 启动内置客户端 redis-cli.exe 3. 简单指令
  2. 图形客户端
 # ping 返回 pang 表示成功!
pang 
# 设置值
set key value 
set name zhangsn 
set age lisi
# 获取值 
get key 
get name 
get age
# 查询所有key 
keys *
# 设置有效期 
setex key senconds value 
setex yanzhengma 60 123456 # 表示验证码1分钟之内有效!

文件说明

  • redis-benchmark.exe 测redis性能的程序,可以同时模拟N多客户端查询和赋值
  • redis-check-aof.exe 更新日志检查–修复日志
  • redis-check-dump.exe 本地数据库检查
  • redis.conf redis配置文件
  • redis-cli.exe 客户端连接 redis服务器工具
  • redis-server.exe redis服务器启动程序

配置说明

配置文件: redis.conf/redis.windows.conf

 #端口 
port 6379 
# 允许远程访问 
bind:绑定IP地址,只允许来自指定网卡的Redis请求,如果想允许任意地址访问将 bind 注释掉就行。 
protected-mode: Redis 安全访护层,默认开启: 
关闭protected-mode模式,此时外部网络可以直接访问 
开启protected-mode保护模式,需配置bind ip或者设置访问密码# (1) 注释 bind 127.0.0.1 
# (2) 如果允许匿名访问,关闭保护模式 
protected-mode no 
# (3) 如果开启保护模式,必须设置请求密码客户端在连接Redis时需要通过【AUTH 密码】命令提供密码 
requirepass 123456 #密码任意 
# 设置 Redis 是否以守护进程模式运行。 (允许后台启动) daemonize yes

启动时指定配置文件

 cd /usr/local/bin 
./redis-server /user/local/etc/redis.conf #指定配置文件启动 (覆盖redis的默认配置)

Reids数据库类型

常用的5种数据类型

  • 字符串
  • Hash(散列值/对象)
  • 集合(Set)
  • 有序集合(zset)
  • 列表(list)

字符串

 # 设置 
set name lisi 
# 获取 
get name 
# 删除 
del name 
# 查询多个 
mget name age 
# 自增 
incr num 
#每次num加1! 变量不存在默认就是1 
# 自减
decr num 
# 长度 
strlen name 
# 是否存在 
exists name

Hash
Hashhash存储对象
工作中使用: 存储各种列表:商品列表.新闻列表,购物车列表.....

 # 设置 
# HSET key field valueHGET key field 
# HMSET key field value [field value …] 多个属性 
# HMGET key field [field …]HGETALL key 
hset car price 500 
hmset car price 500 name baoma

# 获取 
hget 对象名 字段 
hget car price 
hmget car name price

Redis实现缓存
key:value内存数据集,把k:v值保存在内存中,系统访问非常快,是一种内存数据库.内置多种类型,秒杀系统用
到list(排队,队列处理) 库存和界面数据(String)

优缺对比
支持持久化,类型丰富,支持备份,支持集群支持动态添加服务器,内存超出自动保存到磁盘

缺点:单线程,性能略低

  1. redis与memcache的优缺点
  2. Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的
    时候可以再次加载进行使用
  3. Redis不仅仅支持简单的string类型的数据,同时还提供list,set,hash
    等数据结构的存储
  4. Redis支持数据的备份,即master-slave模式的数据备份
    内存超出时redis将不常用缓存swap到磁盘
  5. redis支持集群,添加节点删除节点不丢数据
  6. redis是单线程

使用场景

缓存,集群session一致,聊天室.任务队列,排行榜,收藏夹等, 访问统计

redis应用场景

  1. 缓存
  2. 分布式集群架构中的session分离
  3. 聊天室的在线好友列表
  4. 任务队列。(秒杀、抢购 、12306等等)
  5. 应用排行榜
  6. 网站访问统计
  7. 数据过期处理(可以精确到毫秒)

安装

下载windows版,解压
https://github.com/MicrosoftArchive/redis/releases

  • 文件介绍
    • redis-benchmark.exe #性能测试
    • redis-check-aof.exe # aof更新日志检测
    • redischeck-dumps.exe # 本地数据库检查
    • redis-cli.exe # 客户端
    • redis-service.exe # 服务器
    • redis.windows.conf #配置文件
  • 启动Redis服务

window运行(快捷键 shift+鼠标右键).选择在此打开命令窗口,进入cmd操作系统窗口

 # 启动redis服务 
redis-server.exe redis.window.conf 

# window建议做成*.bat批处理文件 
# linux 做成shell 脚本 *.sh
  • 客户端链接
    进入cmd操作系统窗口
 #运行 
redis-cli.exe 
#如果多服务器时,需要指定端口 
redis-cli.exe -h 127.0.0.0.1 -p 6379 
# 做成批处理

常用指令

事务

redis事务只是原子性操作,无回滚.一次性可以执行多个命名,只是把多个步骤联合为一个整体,内部按照顺
序来执行.

三个阶段:

  • 开始事务multi
  • 命令入队(redis指令)
  • 执行事务 exec

管道Pipeline
管道是批量执行命令可提高执行效率

管道Pipeline
python中可通过管道Pipeline结合MULTI、EXEC实现Redis事务
Pipeline:批量操作命令
当我们要使用事务时:
首先实例化一个Pipeline类,可以先实例化StrctRedis类,然后调用实例
的pipeline()方法;
也可以直接实例化Pipeline类。两种方法都会创建BasePipeLine实例
Redis事务中对应的MULTI、EXEC、DISCARD、WATCH操作都对应到
BasePipeLine中的相应方法

 # 1 
redis = Redis(host='127.0.0.1',port=6379) 
pipe = redis.pipeline() 

# 2 pipe = Pipeline(host='127.0.0.1',port=6379) 
pipe.对应方法() #watch监控key,如果key被改动,事务将被打断

程序使用
redis实现秒杀修改库存,构建队列

Redis实现秒杀修改库存
比如:修改库存(key,产品id,用户id,库存,价格)

 # 秒杀修改库存(key,商品id,用户id,数量,价格) 
def update_store(key,productid,userid,qty,price): 
    qty=int(qty) 
    # 实例化pipline 
    with sec_redis.pipeline() as pipe:
        i = 0 
        # 10次机会(很多人会修改key,当别人修改时,事务就不会执行了.所以多给几次机会) 
        cart_key = 'cart:{}',format(userid) 
        while i<10:
            try:
                #关注一个key,watch字面含义就是监视的意识,这里可以看做数据库乐观锁的概念,谁都 可以读,谁都可以修改,但是修改的人必须保证自己watch的数据没有被别人修改过,否则就修改失败了 
               pipe.watch(key) 
               item = "%s-%s-%s-%s"%(userid,productid,qty,price) 
# 缓存中取出数量,大于qty就开始 
               count = int(pipe.get(key)) 
               if count >= qty: #有库存 
                   #事务开始 
                   pipe.multi() 
                   # 剩余库存=库存-数量 
                   remainqty= count-qty 
                   pipe.set(key,remainqty) 
                   pipe.sadd(cart_key,item) 
                   pipe.execute() 
                   #把命令推送过去, 事务结束 
                   return True 
                   break 
                else:
                   pipe.unwatch() 
                   print("库存不足")
                   return False 
            except Exception: 
               pass 
               continue
            finally: 
               pipe.reset()

Redis构建简单队列

定义队列

 # 定义队列 
queue_prodct_key = 'queue_' + product_key 
que_cart = RedisQueue(queue_product_key) 
que_cart.put(que_user) 
# 数据:list 队列.put(商品1) 
队列.put(商品2) 
队列.put(商品3) 
# 队列方法取 
队列.get() 
#队列取出一位 
user= que_cart.get()

封装Redis 队列RedisQueue

 # 封装redis 队列 RedisQueue 
class RedisQueue(object): 
    """Simple Queue with Redis Backend""" 
    def __init__(self,name,namespace='queue_ms',**redis_kwargs):
       """The defatul connection parameters are: host='localhost',port=6379,db=0""" 
       self.__db= redis.Redis(connection_pool=pool) 
       self.key= "%s:%s"%(namespace,name) 
       def qsize(self): 
       """Return the approximate size of queue""" 
       return self.__db.llen(self,key) 
       def empty(self): 
       """Return True if the queue is empty ,False otherwise""" 
       return self.qsize()==0 
       def put(self,item): 
       """Put item into the queue""" 
       self.__db.rpush(self.key,item) 
       def get(self,block=True,timeout=None): 
       """Romve and return an item from the queue, if optional args block is true and timeout is None(the 
default), block if necessary until an item is avail """ 
       if block: #是否为空 
       item = self.__db.blopo(self.key,timeout=timeout) 
       else:
       item = self.__db.lpop(self.key) 
       if item: 
       item = item[1] 
       return item

Redis 集群配置-Sentinel(哨兵)

开发测试集群组成

  • 一主(6379)
  • 三从(6380-6382)
  • 三哨兵(26379-26381)

三个从服务器配置

 # 第1处: 改端口 
port 6380 
# 第2处更改: 从redis指定主的ip和端口 
slaveof 127.0.0.1 6379

三个哨兵配置

  1. 新建哨兵配置目录
    2.新建配置
    3.拷贝sever和bat启动文件
  2. 更改哨兵端口
  3. 启动

哨兵配置
redissentinel.bat

redis-server.exe sentinel.conf --sentinel

sentinel.conf

 #sentinel.conf 
bind 0.0.0.0 
port 26381 
sentinel monitor seckill 127.0.0.1 6379 1 
sentinel down-after-milliseconds seckill 5000 
sentinel failover-timeout seckill 15000 
logfile "sentinel.log"

启动

  • 分别启动master,slave1,slave2,slave3
 redisrunserver.bat 
(redis-server.exe redis.windows.conf)
  • 启动sentinel
redissentinel.bat 
(redis-server.exe sentinel.conf --sentinel)
  • 启动后页面
  • 链接客户端
# cmd 打开redis-cli 打开master
原文地址:https://www.cnblogs.com/zuohangyu123/p/14151297.html