• redis介绍


    概念
    关系型数据库/sql: mysql,oracle

    非关系型数据库/nosql: redis(存在内存中),mongodb(存在硬盘上)
    
    1.redis是以key-value形式存储
    
    2.redis支持持久化
    

    redis用途

    1.做缓存
    
    2.存储session
    
    3.游戏排行榜
    
    4.对速度要求比较高的数据存储
    
    5.做消息队列
    

    redis 五大数据类型

    1. 字符串
    
    格式:set [key] [value]
    string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
    string类型是Redis最基本的数据类型,一个键最大能存储512MB。
    
    2. 列表
    
    redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素列表的头部(左边)或者尾部(右边)
    格式:lpush [name] [value]  # 在key对应list的尾部添加字符串元素
    格式:rpush [name] [value]  # 在key对应list的头部添加字符串元素
    格式:lrem [name] [index]   # key对应list中删除count个和value相同的元素
    格式:llen [name]           # 返回对应list长度
    
    3. 哈希(字典)
    
    格式: hmset [name]  [key1] [value1] [key2] [value2]
    Redis hash 是一个键值(key=>value)对集合。
    Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
    
    4. 集合(set) 
    
    格式:sadd [name] [value]
    redis的Set是string类型的无序集合
    集合是通过哈希表实现的,所以添加,删除,查找的复杂度都为O(1)
    
    5. 有序集合(zset)
    
    格式: zadd  name score value
    Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
    不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    zset的成员是唯一的,但分数(score)却可以重复。
    

    什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?

    持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失 
    Redis 提供了两种持久化方式:RDB(默认) 和AOF 
    
    RDB(Redis DataBase):
    
    功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数 
    
                    
    
    AOF(Append-only file):
    
         	     
    
    每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作
    	aof写入保存:
    	WRITE:根据条件,将 aof_buf 中的缓存写入到 AOF 文件
    	SAVE:根据条件,调用 fsync 或 fdatasync 函数,将 AOF 文件保存到磁盘中。
    
    比较:
    
    1、aof文件比rdb更新频率高,优先使用aof还原数据。
    2、aof比rdb更安全也更大
    3、rdb性能比aof好
    4、如果两个都配了优先加载AOF
    

    redis有哪些架构,以及特点

    单机版
    
    特点:简单
    缺点:1、内存容量有限 2、处理能力有限 3、无法高可用。
    
    
    
    主从复制 
    
    特点:
    	1、master/slave 角色
    	2、master/slave 数据相同
    	3、降低 master 读压力在转交从库
    问题:
    	1、无法保证高可用
    	2、没有解决 master 写的压力
    
    
    
    Redis 的复制(replication)功能允许用户根据一个 Redis 服务器来创建任意多个该服务器的复制品,其中被复制的服务器为主服务器(master),而通过复制创建出来的服务器复制品则为从服务器(slave)。 只要主从服务器之间的网络连接正常,主从服务器两者会具有相同的数据,主服务器就会一直将发生在自己身上的数据更新同步 给从服务器,从而一直保证主从服务器的数据相同。 
    
    哨兵
    
    特点:
    	1、保证高可用
    	2、监控各个节点
    	3、自动故障迁移
    缺点:
    	主从模式,切换需要时间丢数据
    	没有解决 master 写的压力
    
    
    
    					 
    
    Redis sentinel 是一个分布式系统中监控 redis 主从服务器,并在主服务器下线时自动进行故障转移。其中三个特性:
    监控(Monitoring):   Sentinel  会不断地检查你的主服务器和从服务器是否运作正常。
    提醒(Notification): 当被监控的某个 Redis 服务器出现问题时, Sentinel 可以通过 API 向管理员或者其他应					 用程序发送通知。
    自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时, Sentinel 会开始一次自动故障迁移操作。
    
    集群(proxy 型): 
    
    特点:
    	1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。
    	2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。
    	3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。
    	4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本
    	5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色		 提升。
    缺点:
    	1、资源隔离性较差,容易出现相互影响的情况。
    	2、数据通过异步复制,不保证数据的强一致性
    
    
    
    从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。 
    

    redis常用命令

    Keys [pattern]   			# 查看keys是否存在,Keys * 表示查看所有key
    Exists [key]  				# 查看key是否存在,有返回1,无返回0
    Set [key] [value]   	 	 # 设置键值或修改已有键的值
    Get [key]					# 获取单个值
    Setnx [key] [value]  	 	 # 有则不变,无则设置
    Setex [key] [seconds] [value]	 # 添加并设置过期时间
    Expire [key] [seconds] 	 	 # 设置过期时间
    TTL [key]				    # 查看过期时间
    Mset [key] [value] [key] [value]...  # 设置多个键值
    Getset [key] [value] 	 	 # 修改为新值并返回旧值
    Mget [key] [key]...		 	 # 获取多个值
    Incr [key]					# 使key的值自增1(注意:值必须为整数),若不存在则设置,并返回增后的值
    incrby	[key] [increment]	 # 同Incr,可指定自增的值
    Decr [key]					# 使key的值自减1(注意:值必须为整数),若不存在则设置,并返回减后的值
    Decrby	[key] [decrement]	 # 同Decr,可指定自减的值
    Append [key] [value]		 # 在已有的值后追加字符串,没有则设置
    Strlen [key]				# 返回值的长度
    move [key]	[id]			# 将 key及value移至指定库
    persist [key]				# 取消过期时间
    Select [id]					# 选择数据库0-15
    randomkey					# 随机返回一个kay
    Rename [key]				# 重命名key
    Type [key]					# 返回数据类型
    

    怎么使用redis分布式锁

    先拿setnx来争抢锁,抢到之后,再用expire给锁加一个 过期时间,防止锁忘记释放

    Redis做异步队列

    一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。

    缺点:在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。

    什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?

    缓存穿透
    	一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意	的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。
    如何避免?
    	1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。
    	2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。
    
    缓存雪崩
    	当缓存服务器重启或者大量缓存集中在某一个时间段失效,这样在失效的时候,会给后端系统带来很大压力。导致系统	崩溃。
    如何避免?
    	1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和	写缓存,其他线程等待。
    	2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长	期
    	3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。
    

    比较redis和Memcached

      	      redis      	Memcached
    

    数据类型 字符串,列表,字典,集合,有序集合 字符串
    持久化 支持 不支持
    线程线程 单线程/单进程,但速度非常快 速度较快

    Redis与Mysql双写一致性方案解析

    一、前言:一般用redis来缓存的流程为:

    	但对于更新完数据,先更新缓存,还是先删除缓存有很大争议,因此,进行以下讨论
    

    二、一致性方案

    	1.先更新数据库,再更新缓存
    
    	2.先删除缓存,再更新数据库
    
    	3.先更新数据库,再删除缓存
    

    三、先更新数据库,再更新缓存

    	普遍反对,有两种原因:
    
    1.(线程安全角度)同时请求A和请求B进行更新操作,可能会出现
    	1、A更新了数据
    	2、B更新了数据
    	3、线程B更新了缓存
    	4、线程A更新了缓存
    	*此时缓存中是A的数据
    2.业务场景:
    	*若业务需求是更新远远大于读取,而每次都要更新缓存,则造成很大的性能浪费
    	*若写入的数据不是直接写入缓存,而是要经过一些计算再写入,则也会造成性能浪费。显然,删除缓存更为合适
    

    四、先删除缓存,再跟新数据库

    	也会导致不一致的原因:
    
    -假设线程A进行更新操作,B进行查询操作
    	1、A要更新数据,先删除缓存
    	2、B查询时发现没有缓存
    	3、B去数据库拿到旧值,并写入缓存
    	4、A将新数据写入数据库
    	*此时缓存中依然是旧数据
    -解决方案(延时双删策略):
    	1.先删除缓存
    	2.写入数据库
    	3.休息1s,再删除缓存
    	问题1:1s的时间怎么确定?
    		根据具体的业务情况而定
    	问题2:采用了mysql的读写分离架构怎么办?
    		1、请求A进行写操作,删除缓存
    		2、请求A将数据写入数据库了,
    		3、请求B查询缓存发现,缓存没有值
    		4、请求B去从库查询,这时,还没有完成主从同步,因此查询到的是旧值
    		5、请求B将旧值写入缓存
    		数据库完成主从同步,从库变为新值上述情形,就是数据不一致的原因。解决方案依然是延时双删,在1s后再加		几百ms,等待主从同步完成
    	问题3:第二次删除如果失败怎么办?
    		在下面方案中具体阐述...
    

    五、先更新数据库,再删缓存

    常用的是这种,虽然理论上还是有点问题:
    
    -假设线程A进行查询,线程B进行更新
    	1.缓存刚好失效
    	2.请求A进行查询,查到一个旧值
    	3.请求B进行更新数据库
    	4.请求B进行删除缓存
    	5.请求A将取到的旧值添加到缓存,造成脏数据
    -讨论
    	这种情况发生的情况几乎不存在,因为查询的速度要远大于写入的速度,因此在2进行后不可能会等3,4执行完了,才执行5。那如果删除缓存失败了怎么办?
    
    为了解决删除缓存失败的问题,可用下面两种方案:
    
    一、如图
    
    
    
    二、如图
    
    
    
    备注说明:上述的订阅binlog程序在mysql中有现成的中间件叫canal,可以完成订阅binlog日志的功能。另外,重试机制,可采用的是消息队列的方式。如果对一致性要求不是很高,直接在程序中另起一个线程,每隔一段时间去重试即可,这些大家可以灵活自由发挥,只是提供一个思路。 
    

    python操作redis

    1.简单使用
    
    import redis
    conn = redis.Redis(host='localhost',port=6379)  # 获取reis链接
    conn.set('age','18')  # 存入数据(reids里存的都是byte格式数据)
    name = conn.get('name')  # 获取数据
    print(name)
    
    2. redis连接池
    
    	1.新建一个模块conn_pool.py
    
    import redis
    POOL=redis.ConnectionPool(host='localhost',port=6379,max_connections=1000)
    
    	2.使用连接池
    
    from conn_poll import POOL
    conn=redis.Redis(connection_pool=POOL)
    print(conn.get('name'))
    
    3.需要重点掌握的字符串操作
    
    	get  set  mget  mset  incr  decr  append
  • 相关阅读:
    【STM32F429】第1章 当前主流的小型嵌入式GUI
    【STM32H7】第14章 UDP用户数据报协议基础知识
    【STM32F429】第14章 UDP用户数据报协议基础知识
    【STM32F407】第14章 UDP用户数据报协议基础知识
    【STM32H7】第13章 RL-TCPnet V7.X之创建多个TCP客户端
    【STM32F429】第13章 RL-TCPnet V7.X之创建多个TCP客户端
    【STM32F407】第13章 RL-TCPnet V7.X之创建多个TCP客户端
    【STM32H7】第12章 RL-TCPnet V7.X之TCP客户端
    【STM32F429】第12章 RL-TCPnet V7.X之TCP客户端
    迄今最强综合Demo,H7-TOOL的RTX5全家桶版本整体设计框架
  • 原文地址:https://www.cnblogs.com/gyk1030/p/11691343.html
Copyright © 2020-2023  润新知