redis整理

2018-09-04  本文已影响6人  ant_1024

redis整理

- redis是啥?

- 那么问题来了,为什么性能这么高,也就是为啥快?
  1. redis是以内存作为存储介质。

    • 所以读写效率高。以设置和读写一个256字节的字符串来说,读取速度为11万次/s,写的速度是8.1万次/s
  2. 数据结构是kv

    • 查找复杂度是o(1)
  3. 单线程

    • 避免了频繁的上下文切换
  4. 使用多路复用I/O模型,非阻塞Io

    [图片上传失败...(image-1af1b-1536028551371)]

- 那除了快还有啥特点,memcache也不慢,为啥要用redis?
  1. 支持的类型多,除了支持string,还支持list、set、zset和hash
  2. 支持数据的持久化,可以将内存中的数据存储到硬盘
其他的呢
  1. 支持主从模式,可以配置集群、数据备份。
  2. 支持原子、事务
  3. 支持publish/subscribe, 通知, key 过期等等特性。

- 应用场景呢,干啥能用到啊?

  1. 缓存(热数据)变动比较小的数据
    • 像组织架构。查询比较多的数据,像会员详情。
  2. 单线程,可以避免并发
    1. 计数器 incr,统计访问次数。
    2. 全局增量ID生成,(比如插入会员的时候,在进入队列之后就要返回id,所 以不能等数据库生成id之后再返回)
  3. list类型可以做队列(要求高点的的还是用activeMQ或者其他的吧)
  4. 统计日活跃数(位操作)
    • 每天新建一个byteArray,初始化都是0,member_id作为offset,利用setbit设置为1,统计的时候利用bitcount就可以统计了!
  5. 验证重复请求
    • 将前段的requestIP,参数的hash当做key,设置时间,下次请求如果有这个key,则判断为重复请求,防止刷数据。
  6. 秒杀
    • 把库存放到redis中,秒杀的时候先把库存-1,如果大于0,则成功,否则,失败。不能先判断大于0,然后再-1,会导致超卖。
  7. 最新列表
    • 利用list的lpush即可。
  8. 排行榜
    • 利用有序集合

- redis是放到内存里的,系统重启了不就丢失了吗?

这里就要说说redis的持久化了
主要有两种方式

  1. RDB 不定期的通过异步方式保存到磁盘上(这称为“半持久化模式”)
  2. AOF也可以把每一次数据变化都写入到一个append only file(aof)里面(这称为“全持久化模式”)。
    具体可以参考这篇文章redis持久化

- 现在你搭建了一个redis运行起来了,我想知道redis占用了多少内存

通过redis-cli登陆redis客户端,然后输入info命令,这里我们查看memory

[图片上传失败...(image-828cb7-1536028551372)]

  1. used_memory 是redis分配器分配的内存总量,包括使用的虚拟内存。即used_memory=数据内存+虚拟内存
  2. used_memory_rss 是redis进程占据的系统内存,除了包括分配器分配的内存,还有包括**线程本身运行需要的内存,内存碎片****,不包括虚拟内存!!used_memory_rss=数据内存+线程内存+内存碎片
  3. mem_fragmentation_ratio 内存碎片比率 used_memory_rss/used_memory
name 转化一下
used_memory_rss 数据内存+线程内存+内存碎片
used_memory 数据内存+虚拟内存

啥叫内存碎片:比如对数据修改频繁,且数据大小相差较大,导致redis释放的内存在物理内存中并没有被释放,但redis又无法合理利用,这就会导致内存碎片。

啥叫虚拟内存:就是暂时把不经常访问的数据从内存交换到磁盘中,从而腾出宝贵的 内存空间用于其他需要访问的数据。

redis是如何存储数据的呢!

比如 set hello world (key-->hello value-->world)

typedef struct redisObject {
  unsigned type:4;
  unsigned encoding:4;
  unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
  int refcount;
  void *ptr;
} robj;

struct sdshdr { 
    int len;
    int free;
    char buf[];
};

-然后你发现一个节点不够,怎么搭建集群呢?事务?

[图片上传失败...(image-18e9f4-1536028551371)]

特点:

[图片上传失败...(image-ac9152-1536028551371)]

框架

[图片上传失败...(image-a14c33-1536028551371)]

模块简介

另一个角度架构

[图片上传失败...(image-3c5e81-1536028551371)]

可以参考这个文章写的很不错:redis集群

还需要再研究一下~~~~

主从复制 原理

[图片上传失败...(image-f0c8d3-1536028551371)]

若slave宕机

2.8开始支持增量复制(PSYNC命令)

来看看master的具体工作

[图片上传失败...(image-d5ee6b-1536028551371)]

两个问题

  1. 为什么要定期发送保活命令?

  2. 为什么在发送rdb文件之后,又发送变更命令?

  3. 因为master会不定时发送变更命令,为了防止slave无意义的等待,以此告诉slave,我还活着,不要中断连接。

  4. master保存rdb文件是一个子进程进行的,所以保存期间依然可以处理客户端请求。因此为了保证数据一致性,会再次发送变更命令

分布式锁

参考这篇

事务

link 不支持回滚 出问题 会继续执行

一些面试题

面试题

转载来源:
作者:小绵羊你毛不多
链接:https://www.jianshu.com/p/0000e64bf5f3

上一篇下一篇

猜你喜欢

热点阅读