zoukankan      html  css  js  c++  java
  • 面试-Redis

    为什么Redis的操作是原子性的,怎么保证原子性的?

    对于Redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行。
    Redis的操作之所以是原子性的,是因为Redis是单线程的。
    Redis本身提供的所有API都是原子操作,Redis中的事务其实是要保证批量操作的原子性。

    Redis过期键删除策略

    被动删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key
    主动删除:由于惰性删除策略无法保证冷数据被及时删掉,所以Redis会定期主动淘汰一批已过期的key
    当前已用内存超过maxmemory限定时,触发主动清理策略

    redis 查询单个key内存大小

    MEMORY USAGE keyname
    返回值:the memory usage in bytes

    redis主从复制原理

    复制初始化:当从数据库启动后会向主数据库发送sync命令。主数据库收到sync命令后会开始在保存快照(RDB的过程),并将保存快照期间的命令缓存起来。快照完成后Redis将快照文件和缓存命令发送给从数据库,从数据库载入快照并执行缓存命令。
    运行期间:主数据没收到写命令就会将命令同步给从数据库从而保证主从一致性。

    redis和memcached的区别

    redis支持单核,持久化,有5种数据类型,支持事务
    memcached支持多核,不支持持久化,不支持事务,只有k-v类型

    redis持久化的方式

    RDB(Redis DataBase): 在一定时间内有多少个键被改变后redis会fork一个进程将内存中的数据(fork那一刻的数据)生成快照替换旧的RDB文件
    AOF(Append Only File):在每秒或每次修改都会将数据追加到aof文件中,到达一定的阀值会重写aof文件

    redis 怎么实现分布式锁?

    先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
    如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!
    总的来说,执行上面的set()方法就只会导致两种结果:1. 当前没有锁(key不存在),那么就进行加锁操作,并对锁设置个有效期,同时value表示加锁的客户端。2. 已有锁存在,不做任何操作。

    redis 为什么是单线程的?

    数据都存在内存里,单线程避免多线程多上下文的切换浪费时间

    当list中值被清空时,键还在吗?

    lists,sets, Sorted Sets 和 Hashes,当为空时,都会被自动删除!

    你对Memcach的理解,优点有哪些?

    Memcache是一种缓存技术,在一定的时间内将动态网页经过解析之后保存到文件,下次访问时动态网页就直接调用这个文件,而不必在重新访问数据库。使用memcache做缓存的好处是:提高网站的访问速度,减轻高并发时服务器的压力。
    Memcache的优点:稳定、配置简单、多机分布式存储、速度快。

    缓存穿透+缓存雪崩+缓存击穿?

    缓存穿透:访问一个不存在的key,缓存不起作用,请求会穿透到DB,流量大时DB会挂掉。
    解决方案:采用布隆过滤器,使用一个足够大的bitmap,用于存储可能访问的key,不存在的key直接被过滤;
    访问key未在DB查询到值,也将空值写进缓存,但可以设置较短过期时间。
    缓存雪崩:大量的key设置了相同的过期时间,导致在缓存在同一时刻全部失效,造成瞬时DB请求量大、压力骤增,引起雪崩。
    解决方案:可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效。
    增加二级缓存
    使用队列处理请求
    缓存击穿:一个存在的key,在缓存过期的一刻,同时有大量的请求,这些请求都会击穿到DB,造成瞬时DB请求量大、压力骤增。
    解决方案:在访问key之前,采用SETNX(set if not exists)来设置另一个短期key来锁住当前key的访问,访问结束再删除该短期key。
    热点数据永不过期

    public function get($key) {
        $value = $this->redis->get($key);
        if (is_null($value)) {
            if ($this->redis->setnx($k, $exprieTime)) {
                $value = $this->db->get($key);
                $this->redis->set($key, $value);
                $this->redis->del($k);
            } else {
                usleep(50);
                return $this->get($key);
            }
        }
        return $value;
    }
    
    不积跬步,无以至千里
  • 相关阅读:
    定时刷新
    Codesmith生成oracle、mssql模版中的部分区别和基本功能备忘
    oracle使用中遇到的问题备忘
    存储过程内建临时表和临时函数,合并一个由存储过程返回的表
    烂MP3
    别人笑我太疯癫,我笑别人看不穿
    服务器被挂Iframe木马的解决方法(不是IIS映射修改,也不是ARP病毒,并且网页文件源代码里没有iframe代码的解决方法)
    随便记录下
    重构桌面飘着圣诞老人,利用策略模式和改造的代理模式让软件完全实现开闭原则,欢迎下载源代码分析
    Nhibernate连接oracle数据库报 Could not compile the mapping document异常的解决方法
  • 原文地址:https://www.cnblogs.com/wu-song/p/12345348.html
Copyright © 2011-2022 走看看