zoukankan      html  css  js  c++  java
  • Redis 的原理与应用场景及数据库关系

    个人博客网:https://wushaopei.github.io/    (你想要这里多有)

    一、 Redis 是什么?

    Redis是一个开源的使用ANSIC语言编写、支持网络、单进程单线程、可基于内存亦可持久化的日志型、一个高性能的key-value数据库。

    Redis 的优点:

    • Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
    • Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
    • Redis支持数据的备份,即master-slave模式的数据备份。

    二、Redis 的模式有几种?

    三种,分别为:

    ①单节点模式(配置一个redis);

    ②主从模式(配置一主二从);

    ③哨兵模式(配置一主二从三定点)

    注意: 判断一个主实例的失效需要至少2个Sentinel进程的统一,数量不达标,无法进行failover

    三、对于目前众多的缓存技术中,Redis 和 Memcached等NIO哪一种适合项目中使用?

    • 目前比较主流的缓存技术有Redis和Memcached,单纯从缓存命中的角度来说,Memcached要高一些,可Redis和Memcache的差距其实并不大,但Redis提供的功能更加强大一些,读写速度也很快。所以我们选用了Redis来缓存数据。
    • redis把数据以key—value的形式缓存到内存中,并提供了多种数据存储类型(String、Hash、list、Set、SortedSet),还自身提供了持久化功能(2种:RDB、AOF),还可以把数据备份到磁盘中(redis的SAVE命令用于创建当前 redis数据库的备份),防止redis宕机时的数据丢失。(会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步)。

    四、Redis 为什么可以做缓存?实际项目中使用Redis 的目的是什么?什么时候可以使用?

    1)Redis是key-value形式的nosql数据库。可以快速的定位到所查找的key,并把其中的value取出来。并且redis的所有的数据都是放到内存中,存取的速度非常快,一般都是用来做缓存使用。

    2)项目中使用redis一般都是作为缓存来使用的,缓存的目的就是为了减轻数据库的压力提高存取的效率。

    3)在互联网项目中只要是涉及高并发或者是存在大量读数据的情况下都可以使用redis作为缓存。当然redis提供丰富的数据类型,除了缓存还可以根据实际的业务场景来决定redis的作用。例如使用redis保存用户的购物车信息、生成订单号、访问量计数器、任务队列、排行榜等。

    • redis支持五种数据类型存储:1.字符串2.散列3.列表4.集合5.有序集合

    【1】Hash的特点是什么?比String的好处是?

    Hash比String省内存,将一个对象存储在 hash 类型中会占用更少的内存,并且可以更方便的存取整个对象。新建一个 hash 对象时开始是用 zipmap(又称为 small hash)来存储的。其内存是连续性的,每次增删都会重新分配内存,不存在内存碎片的情况。

    五、Redis 集群中,某个节点宕机怎么办?解决方案是什么?

    • redis集群:一般的是至少是2台服务器,主从服务器!
    • 如果redis集群的主服务器挂了,没有关系还有备服务器 (哨兵模式和集群模式)

    六、 redis怎么保证数据的一致性?

    redis 服务端是单线程处理客户端请求,也就是说客户端请求在服务端是串行化执行的,因此对服务端来说,并不存在并发问题。但业务方却存在并发操作redis中的同一个key的情况。所以如何让A客户端知道B客户端正在操作它想操作的key,就成了必须要讨论的问题。

    解决方案一:

    • 通过对需要操作的key 加锁来保证并发操作的串行化。

    例:

    ②利用MULTI、DISCARD、EXEC 来 使用redis事务操作,对客户端进行串行化。

    七、怎么对Redis 和 MySQL 数据库进行同步?

    背景:当数据库发生异常了,然后数据库对数据进行回滚,而redis缓存中却对数据进行减库存,

    解决方案:

    1. 采用实时同步方案,即查询缓存查询不到再从DB查询,保存到缓存;更新缓存时,先更新数据库,在将缓存的设置过期(建议不要去更新缓存内容,之间设置缓存过期)
    2. 并发高的情况下,采用异步队列的方式同步,可采用kafka等消息中间件处理消息生产和消费。
    3. 重点:使用阿里的同步工具canal,canal实现方式是模拟mysql slave 和 master的同步机制,监控DB bitlog 的日志更新来触发缓存的更新

    八、 redis中的模糊搜索?

    redis中允许模糊查询的有3个通配符,分别是:*,?,[]

    其中:

    • *:通配任意多个字符
    • ?:通配单个字符
    • []:通配括号内的某一个字符

    实际操作中具体的思路:

    1.  将要查询的条件当做key进行ZSet存储
    2. 在获取时,调用StringRedisTemplate.keys(pattern)

    九、Redis实际应用场景?

    【1】显示最新的项目列表

    下面这个语句常用来显示最新项目,随着数据多了,查询毫无疑问会越来越慢。

    SELECT * FROM foo WHERE ... ORDER BY time DESC LIMIT 10 

    假设数据库中的每条评论都有一个唯一的递增的ID字段。我们可以使用分页来制作主页和评论页,使用Redis的模板,每次新评论发表时,我们会将它的ID添加到一个Redis列表:

    LPUSH latest.comments <ID>  

    Redis只需要保存最新的5000条评论,这里我们做的很简单。在Redis中我们的最新ID使用了常驻缓存,这是一直更新的。但是我们做了限制不能超过5000个ID,因此我们的获取ID函数会一直询问Redis。只有在start/count参数超出了这个范围的时候,才需要去访问数据库。

           我们的系统不会像传统方式那样“刷新”缓存,Redis实例中的信息永远是一致的。SQL数据库(或是硬盘上的其他类型数据库)只是在用户需要获取“很远”的数据时才会被触发,而主页或第一个评论页是不会麻烦到硬盘上的数据库了。

    【2】排行榜应用,取TOP N操作

    取最新N个数据的操作以时间为权重,这个是以某个条件为权重,比如按顶的次数排序,这时候就需要我们的sorted set出马了,将你要排序的值设置成sorted set的score,将具体的数据设置成相应的value,每次只需要执行一条ZADD命令即

    //将登录次数和用户统一存储在一个sorted set里
    
    zadd login:login_times 5 1
    
    zadd login:login_times 1 2
    
    zadd login:login_times 2 3//当用户登录时,对该用户的登录次数自增1
    
    ret = r.zincrby("login:login_times", 1, uid)//那么如何获得登录次数最多的用户呢,逆序排列取得排名前N的用户
    
    ret = r.zrevrange("login:login_times", 0, N-1)
    
    

    【3】游戏的排行榜

    比如一个Facebook的游戏,根据得分你通常想要:

    - 列出前100名高分选手

    - 列出某用户当前的全球排名

    • 这些操作对于Redis来说小菜一碟,即使你有几百万个用户,每分钟都会有几百万个新的得分。模式是这样的,每次获得新得分时,我们用这样的代码:
    ZADD leaderboard  <score>  <username>

    你可能用userID来取代username,这取决于你是怎么设计的。得到前100名高分用户很简单:

    ZREVRANGE leaderboard 0 99

    用户的全球排名也相似,只需要:

    ZRANK leaderboard <username>

     

  • 相关阅读:
    form查询相关表
    获取datagrid更新初始值、新值
    数据库约束查询
    强名称工具(来着.NET)
    使用IE插件不能打开的解决
    导入导出报错
    List批量任务多线程执行工具类
    在C#中使用NHibernate框架查询数据
    使用bat文件顺序执行多个应用程序
    用C#实现抽象工厂模式
  • 原文地址:https://www.cnblogs.com/wushaopei/p/11979317.html
Copyright © 2011-2022 走看看