• 第03篇_常见分布式组件

    第01章_Nginx

    第一节 Nginx简介

    1. 什么是Nginx?

    Nginx (engine x) 是一个高性能的HTTP反向代理服务器,支持高达 50,000 个并发连接数,此外,也提供了IMAP/POP3/SMTP等服务。

     

    2. Nginx应用场景

    1) 反向代理

     

     

    2) 负载均衡

    负载均衡指将客户端请求按指定策略分配到不同服务器,以达到平衡负载的效果。Nginx默认支持轮询加权轮询IpHash等负载均衡策略,也支持自定义扩展策略,如fair-根据服务器响应时间来均衡负载。

    img

     

     

    3) 动静分离

    动静分离指将静态文件(如css、html、jpg、js等等文件)直接通过nginx返回,不再经过后台处理,提高资源响应的速度。

    img

     

     

    第二节 安装部署

    1. Windows

     

    2. Linux

     

    3. 关于防火墙

     

    4. 常用命令

     

     

    第三节 配置介绍

    1. 配置总览

     

    2. 全局配置

     

    3. Events配置

     

    4. http块配置

     

    5. server块配置

     

    6. location块配置

    匹配选项含义
    =普通匹配,当请求URL与字符串完全一致时匹配成功
    ~正则匹配,当请求URL包含正则字符串时匹配成功,区分大小写
    ~*正则匹配,当请求URL包含正则字符串时匹配成功,不区分大小写
    ^~普通匹配

     

    第四节 配置示例

    1. 反向代理配置

     

     

    2. 负载均衡配置

     

    3. 动静分离配置

     

    4. 高可用主备配置

    Nginx可基于KeppAlived进行主备配置,当主服务器不可访问时,备服务器将自动接管虚拟IP,处理接入请求。

     

    1) 安装KeppAlived

     

    2) KeepAlived配置

     

    3) nginx_check.sh

     

    4)启动测试

     

     

    第五节 其它配置

    1. 响应压缩

    在http块内或者在单个server块里添加如下配置开启响应压缩:

    然后重载nginx配置文件,在响应报文头中看到 Content-Encoding:gzip 即表示配置成功。

     

    2. 支持HTTPS

    首先通过nginx -V确认是否安装SSL模块(–with-http_ssl_module),然后修改配置文件,添加server配置。

     

    3. 路径重写

    在Nginx中,可以使用rewrite指令进行URL路径的重写:

    如果你想要内部重定向而不改变浏览器的URL,可以使用internal标识符:

    这样,重写操作对用户来说是透明的,浏览器的地址栏不会显示新的URL路径。

     

     

    第六节 常用插件

    Nginx 的插件主要分为以下几类:

     

    1. HTTP 模块插件

    HTTP 模块插件扩展了 Nginx 的 HTTP 功能,包括添加新的 HTTP 模块、自定义请求处理流程等。

    提供 URL 重写功能,可以实现 URL 的重定向、重写等操作。

    提供访问控制功能,可以限制特定 IP 或者网络的访问。

     

    2. 过滤器插件

    过滤器插件对请求和响应进行过滤和处理,如压缩、重写、限速等。

    提供 Gzip 压缩功能,可以减小 HTTP 响应的大小,加快页面加载速度。

    提供 SSL/TLS 加密功能,可以保护 HTTP 通信的安全性。

     

    3. 负载均衡插件

    负载均衡插件实现了负载均衡功能,将请求分发到多个后端服务器,实现高可用性和性能的提升。

    提供负载均衡功能。

    提供 IP 地址哈希负载均衡功能,将同一 IP 的请求分发到同一个后端服务器。

     

    4. 安全插件

    安全插件增强了 Nginx 的安全性,包括防火墙、反爬虫、反盗链等功能。

    提供请求速率限制功能,可以防止恶意请求对服务器造成过载。

    提供连接数限制功能,可以限制每个 IP 的并发连接数。

     

    5. 插件的安装和配置

    下面以stub_status模块为例,简要说明Nginx插件的安装和配置:

    stub_status模块主要用于实现监控功能,简单配置如下:

    最后重载配置文件,访问 http://主机地址/nginx_status 即可测试。

     

     

    第02章_ZooKeeper

    第一节 ZooKeeper简介

    1. 什么是ZooKeeper?

    ZooKeeper 是一个基于观察者模式设计的开源分布式协调服务,它负责存储和管理大家都关心的数据,一旦这些数据发生变化,便会通知相应的观察者做出响应。

    数据模型结构如下,和Unix文件系统非常相似:

    image-20241127101657568

    其中每个节点称为ZNode,可以通过其路径唯一标识,并存储不超过 1MB 的数据。

     

    2. 基本特性

    image-20241127102305707

     

    3. 选举机制

    1) 第一次启动时

    image-20241127110922783

    总结:投票过半数时,服务器 id 大的胜出

     

    2) 非第一次启动时

    image-20241127212539375

    总结: ①EPOCH大的直接胜出 ②EPOCH相同,事务id大的胜出 ③事务id相同,服务器id大的胜出

     

    4. 应用场景

    Zookeeper 提供的服务包括:统一命名服务统一配置管理统一集群管理服务器节点动态上下线(注册中心)软负载均衡等。

     

    1) 统一命名服务

    image-20241127102735347

     

    2) 统一配置管理

    image-20241127105215344

     

    3) 统一集群管理

    image-20241127105329569

     

    4) 注册中心

    image-20241127105403308

     

    5) 负载均衡

    image-20241127105512341

     

     

    第二节 安装部署

    1. 集群部署

    ZooKeeper一般部署为集群模式,且节点数为奇数,如3或5台等,当整个集群中有半数以上的节点存活时,那么整个集群环境才可用。

    服务器台数多:好处,提高可靠性;坏处:提高通信延时。

    image-20241127212709118

    为什么ZooKeeper集群一般为奇数个节点呢?

    答:因为ZooKeeper集群选举leader时,必须要求半数以上的节点通过(不包含半数),因此3台和2台服务器都是要求至少2台可用,整个集群才可用,以防止“脑裂”现象,同理,5台和4台也是类似情况。

     

    1) 前置准备

     

    2) 配置zoo.cfg

     

    3) 创建myid文件

     

    4) 设置环境变量

    修改用户启动配置文件:vim ~/.bash_profile,然后重新加载:source ~/.bash_profile

     

    5) 设置开机启动

    cd /etc/rc.d/init.d目录创建zookeeper服务:vim zookeeper,并授权:chmod +x /etc/rc.d/init.d/zookeeper

    然后添加到开机启动项:chkconfig --add zookeeper,可通过chkconfig --list查看是否添加成功。

    最后,可以通过reboot命令重启机器,查看zookeeper是否开机启动:service zookeeper status

    注意:若出现“服务 zookeeper 不支持 chkconfig”错误,请检查/etc/init.d/zookeeper文件的内容。

     

    2. ZooKeeper启停

    注意:如果查看ZK状态时发现ZK不在运行中,先使用`./zkServer.sh start-foreground查看启动报错信息。

     

    3. 连接ZooKeeper

     

     

    第三节 客户端命令

    1. 查询命令

     

    2. 修改命令

     

    3. 其它命令

     

     

    第四节 客户端API

    1. 基础案例

    注意:

    1. ZooKeeper集群中,只有 Leader 有权限发起数据修改操作,如果向 Follower 发起修改请求,则会转给 Leader 处理。

     

    2. 实现注册中心

    1) 服务注册

     

    2) 服务监听

     

    3) 测试

     

     

    3. 实现分布式锁

    1) 原生方式

     

    2) Curator 方式

    首先需导入 Curator 相关依赖:

    然后创建一个可重入锁并测试:

    提示:

    1. 更多 Curator 框架的用法请参考:https://curator.apache.org/index.html

     

     

    第03章_Kafka

    第一节 Kafka简介

    1. 什么是Kafka?

    Kafka是一个基于 Scala 语言开发的分布式消息队列(Message Queue),也称作分布式事件流平台(Event Streaming Platform)。

    它支持如下两种模式:

    主要的功能如下:

     

    2. 基础架构

    Kafka基础架构图如下:

    image-20241128154659268

     

     

    第二节 安装部署

    1. 集群部署

     

    2. 配置 server.properties

     

    3. 启停命令

     

    4. 配置开机自启

    新建vim /etc/systemd/system/kafka.service文件,内容如下:

    设置开机自启:

     

    5. 常用命令行操作

    1) 主题相关操作

    注意:

    1. 在低版本中,查看所有主题需使用 ./kafka-topics.sh --zookeeper <ZOOKEEPER_ADDRESS> --list命令,其它同理。

     

    2) 生产者相关操作

     

    3) 消费者相关操作

     

    4) 副本相关操作

     

    5) Kafka压测操作

     

     

    第三节 生产者

    1. 消息发送流程

    生产者采用推(push)模式将消息发送到 broker ,具体存储于哪个分区可由生产者指定(指定分区或指定Hash Key)或轮询选出

    image-20241128193826525

    注意:

    1. 分区数据始终先由 Leader 写入磁盘,然后复制给其它 follower 副本。

     

    2. 生产者参数配置

    参数名称参数说明
    bootstrap.servers建立连接用到的Broker列表,以逗号分隔,如:10.201.65.21:9092,10.201.65.22:9092,10.201.65.23:9092;
    key.serializer发送消息时 Key 的序列化器(全类名形式)
    value.serializer发送消息时 Value 的序列化器(全类名形式)
    buffer.memory生产者消息队列(RecordAccumulator)总大小,默认32m
    batch.size消息发送缓冲区大小,默认 16k,提高该值可增加吞吐量,但会增加传输时延
    linger.ms消息发送最多缓冲时间,默认 0ms,即立即发送,生产建议 5-100ms 之间
    acks0:发送后无需等待数据落盘应答,一般不使用;
    1:发送后需等待Leader应答,传输日志数据等;
    -1/all:等待 isr 队列中的所有节点(可同步副本)应答,默认值,传输核心业务数据
    max.in.flight.
    requests.per.connection
    允许最多没有返回 ack 的次数,默认为 5次,开启幂等性时要保证该值是 1-5 。
    retries发送失败后的重试次数,默认为2147483647
    retry.backoff.ms两次重试之间的时间间隔,默认是 100ms
    enable.idempotence是否开启幂等性,默认 true,开启幂等性
    compression.type消息压缩格式,默认是 none,也就是不压缩。支持压缩类型:none、gzip、snappy、lz4 和 zstd。

     

    3. Java API

    1) 导入依赖

     

    2) 同步发送

     

    3) 异步发送

    注意:

    1. 除了自定义分区器外,ProducerRecord类可以直接指定消息发送的分区消息key

    2. 默认的DefaultPartitioner 会优先使用 消息Key 的 hash 值对主题分区数进行取余发送。

    3. 如果既未设置自定义分区器,又未设置消息 Key,则会使用随机粘性分区器(随机分区,但会优先填满目前分区的当前批次)

     

    4) 事务控制

    注意:

    1. 进行事务控制时, 必须开启幂等性,即 enable.idempotence 设置为 true

    2. 必须定义一个唯一的 transactional.id,这样即使生产者客户端挂掉了,重启后也能继续处理未完成的事务

     

    4. Spring Boot API

    1) 导入依赖

     

    2) 生产者配置

     

    3) 发送消息

     

     

    第四节 Broker

    1. ZK节点信息

    image-20241212132329909

    注意:

    1. 消费者在 zk 中注册,但生产者不在 zk 中注册。

     

    2. Broker参数配置

    参数名称参数说明
    replica.lag.time.max.msFollower 向 Leader 发送通信请求/数据的最大间隔,默认30s,超时则会被踢出 ISR 队列
    auto.leader.rebalance.enable自动 Leader Partition 平衡,默认为true
    leader.imbalance.per.broker.percentage每个 broker 允许的不平衡 leader 的比率,默认为10%,超过后将会触发 leader 的平衡
    leader.imbalance.check.interval.seconds检查 leader 负载是否平衡的间隔时间,默认300s
    log.segment.bytes日志块大小,默认1G
    log.index.interval.bytes日志索引间隔,默认4kb,即每写4kb日志文件,则在* index 文件*记录一个索引
    log.retention.hours日志保存的时间,小时级别,默认 7 天
    log.retention.minutes日志保存的时间,分钟级别,默认关闭
    log.retention.ms日志保存的时间,毫秒级别,默认关闭
    log.retention.check.interval.ms检查日志是否过期的间隔,默认是 5 分钟
    log.retention.bytes日志保存的大小,默认-1,表示无穷大
    log.cleanup.policy日志清理策略,默认是 delete,还可设置为 compact,使用压缩策略。
    num.io.threads写磁盘的线程数,默认为8。这个参数值要占总核数的 50%
    num.replica.fetchers副本拉取线程数,这个参数占总核数的 50% 的 1/3
    num.network.threads数据传输线程数,默认为3,这个参数占总核数的50%的 2/3
    log.flush.interval.messages强制页缓存刷写到磁盘的条数,默认是 long 的最大值,9223372036854775807。
    log.flush.interval.ms每隔多久刷数据到磁盘,默认是 null。一般不建议修改,交给系统自己管理。

     

    3. 核心机制

    1) Leader 选举机制

    Controller Leader 负责管理集群 broker的上下线,所有 topic 的分区副本分配Leader 选举等工作。

    image-20241212195311434

    2) Follower故障处理

    image-20241212200435237

     

    3) Leader故障处理

    image-20241212200512208

     

    4) 文件存储机制

    image-20241212201321488

    提示:

    1. 使用 kafka-run-class.sh kafka.tools.DumpLogSegments --files ./00000000000000000000.index 可以查看日志和索引文件。

    2. Broker相关参数可设置文件清理策略,按时间清理或按日志大小清理等。

     

     

    第五节 消费者

    1. 消费流程

    消费者消费者组为单位采用 拉(pull)模式broker 中读取数据,每个分区在同一时间只能由组中的一个消费者进行读取,但是不同组可以同时消费这个分区。

    image-20241128194553991

    注意:

    1. 拉模式可以由消费者控制消息消费的速率,但是消费者可能会在等待消息的“长轮询”中被阻塞

     

    2. 消费者参数配置

    参数名称参数说明
    bootstrap.servers建立连接用到的Broker列表,以逗号分隔,如:10.201.65.21:9092,10.201.65.22:9092,10.201.65.23:9092;
    key.deserializer接收消息时 Key 的序列化器(全类名形式)
    value.deserializer接收消息时 Value 的序列化器(全类名形式)
    group.id标记消费者所属的消费者组
    enable.auto.commit消费者是否向服务器提交偏移量,默认值为 true
    auto.commit.interval.ms消费者向服务器提交偏移量的频率,默认 5s
    auto.offset.reset当 Kafka 中没有初始偏移量或当前偏移量在服务器中不存在的处理方式:
    earliest:自动重置偏移量到最早的偏移量。
    latest:默认,自动重置偏移量为最新的偏移量
    none:如果消费组原来的偏移量不存在,则向消费者抛异常。
    anything:向消费者抛异常。
    offsets.topic.num.partitions__consumer_offsets 的分区数,默认是 50 个分区
    heartbeat.interval.ms消费者和 coordinator 之间的心跳时间,默认 3s,建议小于 session.timeout.ms 的 1/3
    session.timeout.ms消费者和 coordinator 之间连接超时时间,默认45s,超过则移除该消费者,消费者组执行再平衡
    max.poll.interval.ms消费者处理消息的最大时长,默认是 5 分钟,超过则移除该消费者,消费者组执行再平衡
    fetch.min.bytes消费者提取消息最小字节数,默认 1 个字节
    fetch.max.bytes消费者提取消息最大字节数,默认52428800(50 m)
    fetch.max.wait.ms消费者提取消息最长等待时间,默认500ms
    max.poll.records一次 poll拉取数据返回消息的最大条数,默认是 500 条
    partition.assignment.strategy消 费 者 分 区 分 配 策 略 , 默 认 策 略 是 Range + CooperativeSticky
    Kafka 可以同时使用多个分区分配策略,可选:Range、RoundRobin、Sticky、CooperativeSticky。

     

    3. Java API

    1) 导入依赖

     

    2) 从指定主题消费消息

     

    3) 从指定分区消费消息

     

    4) 从指定offset消费消息

     

    5) 从指定时间消费消息

     

    6) 事务控制

    提示:

    1. 消费 offset 保存在内置主题__consumer_offsets中,key 是 group.id+topic+分区号,value 就是当前 offset 的值。

     

    4. Spring Boot API

    1) 导入依赖

     

    2) 消费者配置

     

    3) 消费消息

     

     

    第六节 扩展知识

    1. 生产经验

    1) 生产者精确发送一次

     

    2) 保证分区内数据有序

     

    3) 消费者精确消费一次

     

    4) 如何提高Kafka吞吐量

     

     

    2. Kafka-Eagle 监控

    Kafka-Eagle 框架(https://www.kafka-eagle.org/)可以监控 Kafka 集群的整体运行情况,在生产环境中经常使用。

    image-20241211222552406

     

     

    3. Kafka-Kraft 模式

    Kafka 现有架构中(左图),元数据在 zookeeper 中,运行时动态选举 controller,由 controller 进行 Kafka 集群管理。

    而在 kraft 模式架构中(右图,实验性),不再依赖 zookeeper 集群,而是用三台 controller 节点 代替 zookeeper,元数据保存在controller 中,由 controller 直接进行 Kafka集群管理。 这样做的好处有以下几个:

    image-20241211222901717

     

     

    第04章_Redis

    第一节 Redis简介

    1.什么是Redis?

    Redis(https://redis.io/)是一款C语言开发的高性能键值存储数据库,遵守BSD开源协议。

    扩展

    1. 官方提供测试数据,50个并发执行100000个请求,读的速度是110000次/s,写的速度是81000次/s。

     

     

    2. Redis安装

    1) Windows服务端

     

    2) Linux服务端

     

    3) 图形客户端

     

     

    3. Redis配置

    1) 配置命令

     

    2) 基础配置项

     

    3) 数据存储配置

     

    4) 性能调优配置

     

     

    第二节 常用命令

    1. 基础命令

    1) 连接Redis

     

    2) 运行信息

     

    3) Key 操作

     

    4) 全库操作

     

     

    2. 五种基本类型

    1) String(字符串)

    基于 SDS 字符串实现的Map<String,String>类型结构,可以用来存储任何类型的数据,如:字符串、整数、浮点数、对象等。

    命令介绍
    SET key value设置指定 key 的值
    SETNX key value只有在 key 不存在时设置 key 的值
    GET key获取指定 key 的值
    MSET key1 value1 key2 value2 ……设置一个或多个指定 key 的值
    MGET key1 key2 ...获取一个或多个指定 key 的值
    STRLEN key返回 key 所储存的字符串值的长度
    INCR key将 key 中储存的数字值增一
    DECR key将 key 中储存的数字值减一
    EXISTS key判断指定 key 是否存在
    DEL key(通用)删除指定的 key
    EXPIRE key seconds(通用)给指定 key 设置过期时间

    注意:

    1. String类型的value最大支持512M,单个set和list最大存储 2^32-1 个键值对(40多亿)。

     

    2) List(列表)

    基于双向链表实现的Map<String,List<String>>类型结构,可用作队列

    命令介绍
    RPUSH key value1 value2 ...在指定列表的尾部(右边)添加一个或多个元素
    LPUSH key value1 value2 ...在指定列表的头部(左边)添加一个或多个元素
    LSET key index value将指定列表索引 index 位置的值设置为 value
    LPOP key移除并获取指定列表的第一个元素(最左边)
    RPOP key移除并获取指定列表的最后一个元素(最右边)
    LLEN key获取列表元素数量
    LRANGE key start end获取列表 start 和 end 之间 的元素

     

    3) Hash(哈希)

    基于数组+链表实现的Map<String,Map<String,String>>类型结构,常用于存储对象字段等。

    命令介绍
    HSET key field value设置指定哈希表中指定字段的值
    HSETNX key field value只有指定字段不存在时设置指定字段的值
    HMSET key field1 value1 field2 value2 ...同时将一个或多个 field-value (域-值)对设置到指定哈希表中
    HGET key field获取指定哈希表中指定字段的值
    HMGET key field1 field2 ...获取指定哈希表中一个或者多个指定字段的值
    HGETALL key获取指定哈希表中所有的键值对
    HEXISTS key field查看指定哈希表中指定的字段是否存在
    HDEL key field1 field2 ...删除一个或多个哈希表字段
    HLEN key获取指定哈希表中字段的数量
    HINCRBY key field increment对指定哈希中的指定字段做运算操作(正数为加,负数为减)

     

    4) Set(集合)

    基于哈希表实现的Map<String,Set<String>>类型结构,是不存在重复元素的无序集合,常用于去重、取交集/并集/差集等。

    命令介绍
    SADD key member1 member2 ...向指定集合添加一个或多个元素
    SREM key member1 member2 ...从指定集合移除一个或多个元素
    SMEMBERS key获取指定集合中的所有元素
    SCARD key获取指定集合的元素数量
    SISMEMBER key member判断指定元素是否在指定集合中
    SINTER key1 key2 ...获取给定所有集合的交集
    SINTERSTORE destination key1 key2 ...将给定所有集合的交集存储在 destination 中
    SUNION key1 key2 ...获取给定所有集合的并集
    SUNIONSTORE destination key1 key2 ...将给定所有集合的并集存储在 destination 中
    SDIFF key1 key2 ...获取给定所有集合的差集
    SDIFFSTORE destination key1 key2 ...将给定所有集合的差集存储在 destination 中
    SPOP key count随机移除并获取指定集合中一个或多个元素
    SRANDMEMBER key count随机获取指定集合中指定数量的元素

     

    5) Sorted Set(有序集合)

    基于哈希表+跳表实现的Map<String,SortedSet<String>>类型结构,是不存在重复元素的有序集合,常用于制作排行榜等。

    命令介绍
    ZADD key score1 member1 score2 member2 ...向指定有序集合添加一个或多个元素
    ZREM key score1 member1 score2 member2 ...从指定有序集合删除一个或多个元素
    ZCARD KEY获取指定有序集合的元素数量
    ZSCORE key member获取指定有序集合中指定元素的 score 值
    ZINTERSTORE destination numkeys key1 key2 ...将给定所有有序集合的交集存储在 destination 中,对相同元素对应的 score 值进行 SUM 聚合操作,numkeys 为集合数量
    ZUNIONSTORE destination numkeys key1 key2 ...求并集,其它和 ZINTERSTORE 类似
    ZDIFFSTORE destination numkeys key1 key2 ...求差集,其它和 ZINTERSTORE 类似
    ZRANGE key start end获取指定有序集合 start 和 end 之间的元素(score 从低到高)
    ZREVRANGE key start end获取指定有序集合 start 和 end 之间的元素(score 从高到底)
    ZREVRANK key member获取指定有序集合中指定元素的排名(score 从大到小排序)

    注意:

    1. 如果集合元素较短(<64字节)且元素个数较少(<128个),则会使用 ziplist 存储,以节省内存空间。

    2. 使用跳表不仅能维持比较好的读写平衡,且相对红黑树来说对范围查询更加友好,对B+树来说更节省内存

     

    3. 其它数据类型

    1) Bitmap(位图)

    用于存储二进制,可以理解为bool[512M]类型结构,非常节省内存,常用于活跃用户统计、用户行为分析(登录、点击...)等。

    命令介绍
    SETBIT key offset value设置指定 offset 位置的值
    GETBIT key offset获取指定 offset 位置的值
    BITCOUNT key start end获取 start 和 end 之间值为 1 的元素个数
    BITOP operation destkey key1 key2 ...对一个或多个 Bitmap 进行运算,可用运算符有 AND, OR, XOR 以及 NOT

     

    2) HyperLogLog(基数统计)

    基于矩阵+基数统计的近似算法,能够以极低的内存来估算一个集合中不重复元素的数量,常用于统计页面UV(独立访客量)等。

    命令介绍
    PFADD key element1 element2 ...添加一个或多个元素到 HyperLogLog 中
    PFCOUNT key1 key2获取一个或者多个 HyperLogLog 的唯一计数。
    PFMERGE destkey sourcekey1 sourcekey2 ...将多个 HyperLogLog 合并到 destkey 中,destkey 会结合多个源,算出对应的唯一计数。

     

    3) Geospatial(地理位置)

    用于存储地理位置信息,可以轻松实现两个位置距离的计算、获取指定位置附近的元素等功能,常用于实现“附近的人”功能。

    命令介绍
    GEOADD key longitude1 latitude1 member1 ...添加一个或多个元素对应的经纬度信息到 GEO 中
    GEOPOS key member1 member2 ...返回给定元素的经纬度信息
    GEODIST key member1 member2 M/KM/FT/MI返回两个给定元素之间的距离
    GEORADIUS key longitude latitude radius distance获取指定位置附近 distance 范围内的其他元素,支持 ASC(由近到远)、DESC(由远到近)、Count(数量) 等参数
    GEORADIUSBYMEMBER key member radius distance类似于 GEORADIUS 命令,只是参照的中心点是 GEO 中的元素

     

     

    第三节 高级特性

    1. 发布订阅

    注意

    1. 必须先订阅后发布,订阅某个通道,并不能收到该通道之前已发布的消息。

     

    2. 事务

    1) 事务控制命令

    Redis的事务可以一次执行多个命令,它可以保证:

    注意:

    1. Redis的事务是通过队列实现的,当开启事务时,通过队列收集命令,当提交或回滚时,依次执行或删除队列中的命令。

    2. 当事务中的命令较多时,会阻塞其它客户端请求,并且错误处理不够灵活,报错了还继续执行后续命令。

     

    2) 事务的ACID特性

     

    3. 持久化

    1) RDB方式

    基于某个时间点的数据创建快照,是Redis版本使用的默认方式。

    2) AOF方式

    基于每条更新命令写AOF缓存区(server.aof_buf)和AOF文件(appendonly.aof),再异步根据刷盘策略进行刷盘,当 Redis 重启时,可以加载 AOF 文件进行数据恢复。

    注意:

    1. AOF日志是更新命令执行完毕后再写入的,这样不会阻塞当前命令的执行,但在Redis崩溃或宕机时,可能会丢失该笔日志。

    2. 当AOF文件达到一定大小时(64M),就会触发AOF重写,从Redis读取当前数据并加上期间的增量数据生成新的AOF文件,以节省磁盘空间。

     

    3) 混合持久化

    Redis 4.0 开始支持 RDB 和 AOF 的混合持久化,即在 AOF 重写的时候直接把 RDB 的内容写到 AOF 文件开头,这样可以快速加载同时避免丢失过多的数据,但破坏了AOF文件的可读性。

     

    4. 备份恢复

     

    5. 脚本

    Redis 使用 Lua 解释器来执行脚本,可参考:https://www.redis.net.cn/tutorial/3516.html

     

    6. 管道

    Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。这意味着通常情况下一个请求会遵循以下步骤:

    Redis 管道技术可以在服务端未响应时,客户端可以继续向服务端发送请求,并最终一次性读取所有服务端的响应。

    这可以显著的改善往返时延,提提高Redis的性能。

     

    7. 模块

    Redis 从 4.0 版本开始,支持通过 Module (动态链接库形式)来扩展其功能以满足特殊的需求,推荐的模块如下:

     

    8. 性能测试

     

     

    第四节 Java客户端

    1. Jedis

    1) 引入依赖

     

    2) 连接Redis

     

    3) 数据存取

     

    4) 其它命令

     

    5) Jedis连接池

    注意:

    1. Jedis连接使用完毕后,必须调用jedis.close();归还连接。

     

    2. RedisTemplate

    1) 引入依赖

     

    2) 注入StringRedisTemplate使用

     

    3) 注入RedisTemplate使用

    RedisTemplate允许你以Java对象的形式存取数据。

    但其默认采用JDK序列化机制,阅读能力差,而且占用空间大,一般需要人为指定序列化方式:

     

     

    第五节 面试扩展

    1. Redis基础

    Redis为什么快?

     

    Redis vs Memcached?

     

    为什么不使用Redis作为主数据库?

     

    2. Redis应用

    Redis 除了做缓存,还能做什么?

     

    为什么不建议使用Redis作消息队列?

     

    Redis 可以做搜索引擎么?

     

    如何基于 Redis 实现延时任务?

    3. Redis线程模型

    Redis是单线程还是多线程?

    在这里插入图片描述

     

    Redis使用单线程模式的优劣势?

     

    Redis6.0之后为什么引入多线程?

    主要是为了提高网络 IO 读写性能,因为这个算是 Redis 中的一个性 能瓶颈(Redis 的瓶颈主要受限于内存网络)。

     

    Redis 6.0 新增的异步命令有哪些?

     

    Redis后台线程有哪些?

     

    4. Redis内存模型

    为什么要设置数据过期时间?

    扩展:

    1. Redis是通过过期字典(可以看作是 hash 表)来实现数据过期的,查询数据前会先查询过期字典进行检查。

     

    过期 key 删除策略有哪些?

     

    Redis默认的过期key清理策略是什么?

     

    大量 key 集中过期怎么办?

     

    Redis 内存淘汰策略了解么?

    注意:

    1. Redis 的内存淘汰策略只有在运行内存达到了配置的最大内存阈值(maxmemory 参数)时才会触发,默认为 0 ,表示不限制。

     

    Redis内存碎片

     

    5. Redis生产实践

    常见性能调优

     

    常见缓存问题

     

    如何保证缓存和数据库的一致性?

    常见缓存读写策略?

     

    常见阻塞原因?

     

     

    第05章_Quartz

    第一节 Quartz简介

    1. 什么是Quartz?

    Quartz是一款基于Java实现的开源的任务调度库,体系结构如下:

    img

    核心组件包括:

    扩展:

    1. 任务调度指系统中创建了 N 个任务,每个任务都有指定的时间进行执行,而这种多任务的执行策略就是任务调度。

     

    2. Quartz示例

    1) 引入Quartz相关依赖

     

    2) 自定义任务

    默认情况下,Job是无状态的,每次都会创建新的实例,上下文中的JobDataMap也是新的。可以在Job类上加上@PersistJobDataAfterExecution注解,则会变成有状态的Job,允许将数据传递给下一个Job,如统计Job执行次数。

     

    3) 创建任务调度

     

    3. SpringBoot整合

    1) 引入依赖

     

    2) 定义Job

     

    3) 手动执行

     

    4) 自动执行

    将 JobDetail 和 Trigger 注册为Bean,任务就会随Spring启动而自动触发执行,这对需要随程序启动而执行的作业非常有用。

     

     

    4. 集群模式

    集群模式可以防止单点故障,减少对业务的影响,同时可以分散单个节点的压力,提升集群整体处理能力。

    Quartz基于数据库实现了集群模式,支持高可用、负载均衡(随机算法)、故障恢复等。

     

    1) 添加数据库相关依赖

     

    2) 添加集群配置

     

    3) 创建SchedulerFactory

     

    4) 注意事项

     

     

    第二节 常用类详解

    1. Job和JobDetail

    Job是任务的顶层接口,承载具体的业务逻辑,每次调用时都会创建新的实例对象。

    JobDetail是任务的调度信息,可以构建和设置Job实例。

     

    2. JobExecutionContext

    Job执行的上下文信息,可以访问到 Quartz 运行时的环境以及 Job 本身的明细数据。

     

    3. JobDataMap

    一个键为String,值为Object类型的Map,用于存储和传递数据,存在于JobDetail和Trigger等中。

    在Job类中,可以通过JobExecutionContext获取设置的数据,或通过Quartz框架进行注入。

     

    4. Trigger

    Trigger用于指定任务触发的时机,其接口和实现类如下,我们一般使用 SimpleTriggerCronTrigger 两种。

    img

     

    1) SimpleTrigger

    SimpleTrigger适用于在特定的日期(或时间)启动,以固定的间隔时间重复执行 n 次的Job任务。

     

    2) CronTrigger

    CronTrigger是基于日历的作业调度器,可以做到某个时间点执行,例如“每天的凌晨1点”、“每个工作日的12点”等。

     

     

    5. Scheduler

    调度器(Scheduler)负责将任务(Job)和触发器(Trigger)整合起来,基于Trigger设定的时间来执行Job。

     

    1) 创建和使用

     

    2) 标准调度器

    quartz.properties 文件配置示例如下,更多配置可参考 StdSchedulerFactory 类代码。

     

    6. Listener

    监听器(Listener)用于监听特定事件的发生,以便做出对应的处理,包括任务监听器、触发器监听器、调度器监听器。

     

    1) JobListener

     

    2) TriggerListener

     

    3) SchedulerListener

     

    4) 注册Listener

     

    7. JobStore

    作业存储(JobStore)用于定义Quartz运行时任务的存储方式。

     

    1) RAMJobStore

    RAMJobStore是基于内存的存储模式,调度信息保存在内存中,性能较高,但应用程序结束或崩溃时数据将丢失。

     

    2) JDBCJobStore

    JDBCJobStore是基于数据库的存储模式,调度信息保存在数据库中,可以持久化保存调度信息,但是性能取决于数据库性能。

    下面是使用步骤:

    执行任务调度后,可以在 QRTZ_JOB_DETAILS 表查看任务明细数据。

    image-20240510153401393

     

     

    第三节 扩展补充

    1. Cron表达式简介

    Cron表达式由7个子表达式组成,分别是:

    字段是否必填允许值可用特殊字符
    0-59, - * /
    0-59, - * /
    0-23, - * /
    日(月中的哪几天)1-31, - * / ? L C W
    1-12 或 JAN-DEC, - * /
    周(周中的哪几天)1-7 或 SUN-SAT, - * / ? L C #
    不填写 或 1970-2099, - * /

    可用的特殊字符及含义如下:

     特殊字符含义
    *可用在所有字段中,表示对应时间域的每一个时刻,如:在分钟字段时,表示“每分钟”
    ?该字符只在日期和星期字段中使用,它通常指定为“无意义的值”,相当于点位符
    -表达一个范围,如在小时字段中使用“10-12”,则表示从10到12点,即10,11,12
    ,表达一个列表值,如在星期字段中使用“MON,WED,FRI”,则表示星期一,星期三和星期五
    /x/y表达一个等步长序列,x为起始值,y为增量步长值。如在分钟字段中使用0/15,则表示为0,15,30和45秒,而5/15在分钟字段中表示5,20,35,50,你也可以使用*/y,它等同于0/y
    L该字符只在日期和星期字段中使用,代表“Last”的意思,但它在两个字段中意思不同。L在日期字段中,表示这个月份的最后一天,如一月的31号,非闰年二月的28号;如果L用在星期中,则表示星期六,等同于7。但是,如果L出现在星期字段里,而且在前面有一个数值X,则表示“这个月的最后X天”,例如,6L表示该月的最后星期五
    W该字符只能出现在日期字段里,是对前导日期的修饰,表示离该日期最近的工作日。例如15W表示离该月15号最近的工作日,如果该月15号是星期六,则匹配14号星期五;如果15日是星期日,则匹配16号星期一;如果15号是星期二,那结果就是15号星期二。但必须注意关联的匹配日期不能够跨月,如你指定1W,如果1号是星期六,结果匹配的是3号星期一,而非上个月最后的那天。W字符串只能指定单一日期,而不能指定日期范围
    #该字符只能在星期字段中使用,表示当月某个工作日。如6#3表示当月的第三个星期五(6表示星期五,#3表示当前的第三个),而4#5表示当月的第五个星期三,假设当月没有第五个星期三,忽略不触发

    Cron表达式对特殊字符的大小写不敏感,对代表星期的缩写英文大小写也不敏感。

     

    2. Quartz表结构

     

     

    第06章_Elasticsearch

    第一节 索引操作

    1. 创建索引

     

    2. 删除索引

     

    3. 查看索引信息

     

     

    第二节 映射操作

    1. 创建映射

     

    2. 查看映射信息

     

     

    第三节 数据增删改

    1. 新增数据

     

    2. 修改数据

     

    3. 删除数据

     

    4. 批量新增

     

     

    第四节 数据查询

    1. 查询所有数据

     

    2. 分词匹配查询

    1) 分词or匹配
    2) 分词and匹配
    3) 分词比例匹配

     

    3. 多字段分词匹配查询

     

    4. 词条匹配查询

     

    5. 范围查询

     

    6. 模糊查询

     

    7. 布尔查询(高级查询)

     

    8. 查询过滤

     

     

    第五节 结果集操作

    1. 结果列过滤

     

    2. 结果排序

    1) 单字段排序
    2) 多字段排序

     

    3. 结果聚合

    1) 聚合为桶
    2) 桶内度量
    3) 桶内嵌套桶
    4) 阶梯分桶