Redis

作者: bowen_wu | 来源:发表于2022-01-24 21:11 被阅读0次

    概述

    • 广泛使用的内存缓存
    • 使用多路IO进行事件驱动的单线程处理所有事件的操作
    • 启动 Redis => docker => docker redis => 默认端口映射 6379 => docker run --name first-redis -p 6379:6379 -d redis

    操作系统基本原理

    1. CPU 是时钟驱动的,基本执行单位是指令
    2. 指令来自程序的代码段
    3. CPU 读取程序的代码段,挨个执行指令
      • 可以从内存和寄存器交换数据
      • 可以执行计算
      • 可以跳转
    4. 某一个时刻只有一个进程或线程占有 CPU,执行指令

    当上下文切换发生时

    CPU 需要:

    1. 保存现场 => 正在执行的任务的所有寄存器
    2. 恢复现场 => 即将被执行的任务的所有寄存器

    上下文切换有多慢: 切换上下文需要数千个时钟周期

    Redis 为什么这么快

    • 完全基于内存 => CPU(10^-9 s == 1ns) 比内存快3个数量级,内存比硬盘快3个数量级 => CPU 是时钟周期驱动的,CPU的速度比内存快大约3个数量级
    • 优秀的数据结构设计
    • 单一线程,避免上下文切换的开销和避免锁的开销
    • 事件驱动,非阻塞
    • IO 多路复用机制

    IO 多路复用机制

    • 如何从操作系统的 IO 中读写数据? => recv(receive)/send 系统调用(recv/send 默认阻塞) => 阻塞了多个线程 => 线程昂贵 + 上下文切换 => IO 多路复用:一个线程可以同时服务海量的 Socket 连接

    IO 模型

    • Blocking IO => recv 阻塞至有数据返回 => FileInputStream.read() => Reads a byte of data from this input stream. This method blocks if no input is yet available.
    • Non-blocking IO => 如果无数据,recv 立即返回,给出一个状态码

    多路 IO

    • 同时监控多个 Socket
    • select | poll
      • 监控多个 file descriptor(FD 文件描述符)
      • 功能几乎相同,共用代码
      • 当返回时,需要轮询 PF 列表检查是否有事件发生
    • epoll => 当返回时,只要有事件发生的 FD 会被返回 => Redis 使用 epoll

    数据结构

    Structure Type What is contained
    String String, Integers, or floating-point values
    List Linked list of strings
    Set Unordered collection of unique strings
    Hash Unordered hash table of keys to values(Java HashMap, key-value must be a string)
    ZSet(sorted set) Ordered mapping of string members to floating-point scores, ordered by score(有序的集合, TreeSet)

    Spring Boot Redis

    • @Bean
    1. 创建 RedisTemplate
    2. @Autowired RedisTemplate

    Redis 存在最大的意义在于在多个机器分布式集群中共享数据

    Java Object 序列化 => 字节流 => java.io.Serializable

    在 Spring Boot 中使用 Redis

    1. docker 启动 Redis 服务
    2. 配置 Redis Spring Boot starter
    3. 在 Spring 中配置 Redis
      spring.redis.host=localhost // 本机
      spring.redis.port=6379
      
    4. 配置 Redis Template
      @Configuration
      public class ApplicationConfig {
          @Bean
          RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
              RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
              redisTemplate.setConnectionFactory(redisConnectionFactory);
              return redisTemplate;
          }
      }
      
      注意
    5. 在使用的地方注入即可

    知识点

    1. 阻塞 vs 死循环
      • 阻塞 => 不占用 CPU
      • 死循环 => 占用 CPU 100%
    2. Java 中一个线程大约占用 1M - 4M 的内存 => 一个 JVM 中最多就开几千个线程
    3. // TODO: bitmap

    相关文章

      网友评论

          本文标题:Redis

          本文链接:https://www.haomeiwen.com/subject/nhhihrtx.html