Redis的前世今生

基本介绍

#### 数据存储演变过程

illustration

  • 数据存储在文件中:查找数据造成全量扫描-受限于磁盘IO的瓶颈
  • 关系型数据库:关系型数据库是行级存储-会空出来没有数据列-受限于磁盘IO的瓶颈
  • 数据库放入缓存:受限于硬件-成本高illustration
  • 数据的存储方式受限于:

  • 冯诺依曼体系的硬件制约
  • 以太网, TCP/IP 的网络
  • Redis的特点-对比Memcache , value有类型 , 有类型对应的方法(API) , 计算向数据移动

    illustration

    #### 安装

    illustration

    ``plain centos 6.xredis官网5.xhttp://download.redis. io/releases/redis-5.0.5.tar.gz1 , yum install wget2,cd ~3,mkdir soft4,cd soft5,wget http://download.redis.io/releases/redis-5.0.5.tar.gz6,tar xf redis.. tar.gz7,cd redis-src8,看README md9, make.. install gcc..... make distclean10,make11,cdsrc .. .生成了可执行程序12, cd ..13,make install PREFIX=/opt/mashibing/redis514,vi /etc/profileexport REDIS_ _HOME= /opt/mashibing/redis5export PATH= $PATH:$REDIS_ _HOME/bin.source /etc/profile15,cd utils16,./install_ server.sh ( 可以执行- -次或多次))一个物理机中可以有多个redis实例(进程) ,通过port区分b)可执行程序就-份在目录,但是内存中未来的多个实例需要各自的配置文件,持久化目录等资源 c) service redis_ 6379 start/stop/stauts > linux /etc/init.d/***d)脚本还会帮你启动!17.ps -fe| grep redis `

    illustration illustration illustration

    #### BIO->同步非阻塞NIO->多路复用NIO

    内核不断变化

  • BIO阻塞: 读一个socket产生的文件描述符, 如果数据包没到, read命令就不能返回, 在这阻塞着, 抛出一个线程在这阻塞着, 有数据就处理, 下边的代码执行不了, 其他线程无法处理已到达的数据, socket是阻塞的
  • 一个线程的成本: 线程栈是独立的, 默认1MB, 线程多了, 调度成本提高. CPU浪费, 占用内存多
  • 同步非阻塞NIO: 遍历, 取出来处理, 都由自己来完成, 同步非阻塞, 每个连接都要掉一次内核
  • 多路复用NIO: 内核select(), 允许一个程序监视多个文件描述符, 等待直到一个或多个文件描述符准备好, 就能触发I/O操作了 , 一次系统调用读若干个, 返回有数据的, 减少用户态内核态切换 , 选择有数据的, 直接读
  • 共享空间: 文件描述符都是累赘, 减少内核区域和用户空间之间传参, 把用户空间和内核空间建立映射, 相当于创建共享空间, 通过mmap系统调用, 红黑树+链表, 进程里有文件描述符就往红黑树里放, 内核可以看到, 把到达的放到链表里, 如果
  • illustration

    Redis进程的文件描述符 0: 标准输入 1: 标准输出 2: 报错输出 3,4: pipe调用 5: epoll

    kafka: sendfile + mmap 零拷贝: sendfile系统调用

    illustration

    Redis为什么快: epoll : epoll是 Linux内核 为处理大批量 文件描述符 而作了改进的poll-是Linux下多路复用IO接口select/poll的增强版本-它能显著提高程序在大量 并发连接 中只有少量活跃的情况下的系统 CPU利用率。另一点原因就是获取事件的时候-它无须遍历整个被侦听的描述符集-只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。

    顺序性: 每个连接内的命令顺序 内存寻址是ns级, 网卡是ms级, 10万倍差距, 10万连接同时时到达, 可能会产生秒级响应 mysql开启缓存, 想模仿redis, 性能反而会低, 多了一次判断过程, 增加了内存空间占用

    #### 类比Nginx

    illustration illustration

    5种数据类型

    illustration

    illustration

    可以根据用户的指令, 看是不是和key里存的type匹配, 不匹配直接返回, 规避异常

    illustration

    nx: 只能新建 分布式锁 xx: 只能更新

    #### String

    illustration

    illustration

    illustration

    二进制安全: Redis只取字节流, 一个字符一个字节

    illustration illustration illustration

    和Xshell设置有关

    illustration

    GETSET减少一次I/O

    illustration

    MSETNX原子性set, k2已经存在, 集体失败

    illustration

    ##### bitmap (活跃度|登录数)

    illustration illustration

    按位与

    Weiguang Li

    Weiguang Li

    Java Backend Engineer specializing in Spring Boot, distributed systems, and microservices. Passionate about clean code and continuous learning.