网站模块制作ppt教程视频自学
web/
2025/9/30 20:53:34/
文章来源:
网站模块,制作ppt教程视频自学,网站优化服务合同,网站建设的环境一、ES 场景#xff1a;某头部互联⽹公司的好房业务#xff0c;双⼗⼀前⼀天#xff0c;维护楼盘的运营⼈员突然接到合作开发商的通知#xff0c;需要上线⼀批热⻔的楼盘列表#xff0c;上传完成后#xff0c;C端⼩程序⽀持按楼盘的名称、户型、⾯积等产品属性全模糊搜索…一、ES 场景某头部互联⽹公司的好房业务双⼗⼀前⼀天维护楼盘的运营⼈员突然接到合作开发商的通知需要上线⼀批热⻔的楼盘列表上传完成后C端⼩程序⽀持按楼盘的名称、户型、⾯积等产品属性全模糊搜索热⻔楼盘。 需求按楼盘的名称、户型、⾯积等产品属性全模糊搜索双⼗⼀期间楼盘搜索QPS预计在800左右搜索完成后展示的楼盘字段信息⾮常多 业界数据一致性解决方案 ES与数据库双写方案 实现方案 运营后台导⼊楼盘的时候先批量操作本地的数据库然后再批量同步写⼊到es这两步操作放到同⼀个事务中如果写⼊数据库成功调⽤es失败抛出异常spring事务会回滚数据库记录。如果写⼊数据库成功调⽤es超时了但实际上es是成功的只是接⼝返回的数据慢了抛出异常这个时候spring事务也会回滚数据库记录从⽽会导致数据库和es的数据出现不⼀致。
优点 实现非常简单不引入任何中间件数据同步实时 缺点 业务逻辑中直接写入es有一定的侵入性 数据不一致es异常事务回滚 数据库本地事务调用eses超时会引起接口长事务长时间占用数据库链接 应用场景 系统特点旧系统年限长单体架构且技术比较落后如果引入除ES之外的其他中间件治理成本很高可以考虑这个方案 业务场景用户量少偏后台管理类的系统对数据同步的实时性要求很高接近实时 MQ异步写入方案 实现方案
优点 通过引入MQ实现异步削峰提升接口的整体性能 通过本地消息表定时任务重试有效保证 缺点 引入MQ中间件系统复杂度增加 MQ有积压风险会存在延时的风险 应用场景 系统特点C端系统系统架构已引入MQ中间件对接口TPS有一定性能要求 业务场景用户体量大高并发场景同一业务变更的地方少允许有一定的延迟(秒级) 定时任务同步方案 实现方案 前提条件楼盘信息更新的时候必须更新mysql楼盘表中的更新时间字段。 这⾥需要考虑两个核⼼点1、控制好定时任务执⾏的频率 2、定时任务采⽤增量同步深度分⻚分批处理数据
优点 对业务无侵入性 缺点 实时性很差 轮询数据库数据量比较大的时候会存在性能问题 频繁扫库处理大数据量的表数据库本身压力非常大 应用场景 系统特点旧系统年限长技术框架老旧引入其他的中间件成本很高 业务场景用户体量小偏报表统计类业务对数据实时性要求不高 监听binlog异构同步方案 实现方案
优点 对业务无任何侵入性解耦数据同步准实时 缺点 需要引入第三方canal数据同步中间件 binlog同步不及时会有一定的数据延迟毫秒级 应用场景 系统特点C端系统开放mysql binlog日志监听引入第三方canal中间件成本不高 业务场景互联网公司用户体量大大型多中心组织高并发场景业务上允许有一定的延迟秒级 数据快速修复解决方案
发现问题 搭建业务监控平台配置业务监控 定位问题 开发问题诊断平台可视化定位问题 快速修复问题 捞数补数 代码落地实现 基于监听binlog方案的代码实现 1redis与mysql数据⼀致性如何保证 答优先考虑基于binlog监听的⽅案实现。 2本地缓存、redis与mysql三者之间的数据⼀致性如何保证 答⽤户在管理后台针对特定的功能记录新增或修改后后端接⼝会先将数据记录写⼊到数据库然后再发送MQ⼴播消息(或者基于redi实现⼴播通知)各个应⽤节点接收到MQ⼴播消息后分别从数据库中查询记录然后再刷新到本地缓存、redis缓存从⽽保证三者之间的数据⼀致性。 二、Redis分布式锁 分布式锁 JVM锁单机 同一个JVM进程内种多线程并发访问资源的安全性一般使用JDK自带的synchronized或lock锁 分布式锁集群 不同进程多线程并发访问资源的安全性一般采用mysqlzkRedis实现 应用场景 悲观锁当查询某条记录时就让数据库为该记录加锁锁住记录后别人无法操作 缺点可能出现死锁并发性能差 乐观锁修改事务隔离级别RC 读已提交的 缺点并发性能差 redis分段预扣库存和异步消息写入db 申请阶段将库存扣减转到redis进行一般对redis锁进行分段处理 确认阶段引入mq串行处理超过阈值就不在消费队列 缺点异步写入DB有数据不一致的风险告警机制和补偿措施 实现
1加锁 2执行业务逻辑 3释放锁 SpringBoot实现方式 自定义分布式注解 lock AOP开发一个切面拦截类封装加锁和解锁逻辑 引入Spring-data-redis驱动包集成redis某个客户端 redis客户端 redislua jedis lettuce redission 1redis 除了做缓存还可以用来做什么 答分布式锁、防重提交、分布式限流、简易版本的消息队列、延迟任务、session 共享集成spring-session-data-redis 2redis 锁如何保证任何时刻有且只有一个线程持有这个锁 答使用命令setnx key value key不存在时设置成功返回值okkey存在设置失败也可以采用If(!redisUtil.get(key)){set key value}, 不过这段代码需要采用 lua 脚本实现来保证原子性。 3如何保证分布式锁不产生死锁 答给锁设置一个合理的过期时间业务执行过程中节点异常宕机有个兜底终止跳出方案 使用命令setnx key value ex seconds 设置key和对应的过期时间到了指定的ex时间锁自动释放。 4如何防止释放别的线程锁 答给锁设置一个当前线程id或uuid的值释放锁的时候判断锁的值与当前的值是否相等 5锁到期了业务没执行完如何保证数据的一致 答常见的处理办法就是采用看门狗机制对分布式锁进行续命具体步骤如下所示 当前线程加锁成功后假设设置默认过期时间为30秒会注册一个定时任务监听这个锁每隔30/310 秒就去查看这个锁如果还持有锁就对锁的过期时间继续续命30秒如果没持有锁就取消定时任务。这个机制也被叫做看门狗机制. 6怎么保证分布式锁可重入 答通过维护当前持有锁的计数来实现可重入功能。加锁的时候第一次获取锁时保存锁的线程标识后续再次获取锁先看是否是同一个线程如果是的话只对锁计数进行递增。解锁时对锁计数进行递减同时刷新锁的过期时间。如果计数为0最终才释放锁。 7如何解决redis主从节点不同步导致锁失效的问题 答采用红锁算法解决这个锁失效问题红锁算法认为只要(N/2) 1个节点加锁成功那么就认为获取了锁解锁时将所有实例解锁。 8如何优化高并发下锁性能 答与ConcurrentHashMap 的设计思想有点类似用分段锁来实现。 实现方案 1redis 分布式锁推荐 互联网项目并发量高对性能要求高比较推荐。 redis 常见操作例如基本类型string、hash、list、set等等操作可以采用jedis或lettuce。 对于跟分布式锁相关的操作集成redission。 2分布式锁百分百可靠 可以选用 Zookeeper作为分布式锁。采用cap理论中的cp模型保证高可靠性。 一般的项目我们可以结合不同的场景同时兼容两种分布锁的实现。 三、Redis主从复制 主从复制将一台Redis服务器的数据复制到其他的Redis服务器复制是单向的采用读写分离模式。 工作原理 slave节点初次连接master节点会发送psync命令并触发全量复制此时master节点fork一个后台进程开始生成一份RDB快照同时将那些从外面接收的写命令缓存到缓冲区中slave先写入磁盘再从磁盘加载到内存接着master会将新增加的缓存区的写命令发送给slave执行并同步数据
全量复制
增量复制
1redis主从节点是长连接还是短连接 答长连接 2怎么判断redis某个节点是否正常工作 答通过相互的ping-pong心跳检测机制有一半以上的节点没回应则断掉这个节点连接 3过期的key如何处理 答主节点处理一个key或者通过淘汰算法淘汰一个key主节点模拟一条del命令发送给从节点从节点接收到命令删除key 4redis是同步复制还是异步复制 答redis主节点每次接收到写命令之后先写到内部的缓冲区然后异步发送给从节点 5redis主从切换如何减少数据丢失 异步复制同步丢失 答client端采取降低措施将数据暂时写入本地缓存和磁盘中在一段时间后重新写入master来保证数据不丢失也可以将数据写入rocketmq消息队列发送一个延时消费消息去写入master 集群产生脑裂数据丢失 答在redis的配置文件中有两个参数设置 min-slaves-to-write min-slaves-max-lag 6redis主从如何做到故障自动切换 答哨兵模式当主节点出现故障由redis sentinel自动完成故障发现和转移并通知应用方实现高可用性 7数据备份方式有哪些 热备
冷备
多活
四、Redis高可用 Redis主从复制模式 原理 1 个master 节点可以挂多个slave节点master节点负责请求的读写slave节点负责请求的读当数据写入master节点通过主从复制将数据同步到slave节点从而实现高可用。 缺点 当主从节点异常或宕机后需要一个监控工具监听所有的节点出现问题后发出邮件告警人工进行干预调整主从节点相对耗时而且造成服务不可用 Redis哨兵模式 原理 它是在主从复制方案的基础上引入了一组哨兵节点来实现高可用的哨兵节点是独立的进程独立运行的。 作用 监控 告警提醒 自动故障转移 通知客户端连接新的masterraft协议保存数据的一致性通过ping的方式探活 缺点 内存利用率低 高并发写入QPS有限 Redis Cluster集群模式 原理 通过对redis数据分片实现redis的分布式存储cluser集群采用去中心化的思想节点之间的通信采用gossip二进制协议master节点负责请求的读写slave 节点不参与请求的处理只作为master的备份。 redis 如何实现数据分片 Redis 通过引入hash槽的概念集群预先分配16384个槽slot并将槽点分配具体的服务节点每个节点负责一部分槽点数据的存储这样数据就分散到多个节点突破了redis单机内存的限制存储容量大大增加。 数据如何进行存取 当接受到客户端的请求通过对应进行crc16(key) % 16384 取模运算得到对应的槽从而将读写操作转发到具体的服务节点当数据写入对应的master节点后数据会同步到这个master的所有slave节点。 如何实现高可用 采用主从复制模式来保证高可用一个主节点对应多个从节点主节点提供存取从节点从主节点复制数据进行备份当这个主节点挂掉以后选取一个从节点充当主节点从而保证集群节点不会挂掉。节点之间通过gossip协议交换信息每个节点除了存取数据还会维护整个集群的节点信息。 缺点 是无中心节点架构依靠二进制协议协同自动化修复节点之间不断进行心跳机制造成大量IO 数据迁移需要人工接入大key的迁移有可能导致自动故障转移造成不必要的切换 五、Redis热key解决方案 利用本地缓存guava cache 或 caffeine 在你发现热key以后把热key加载到系统的JVM中。针对这种热key请求会直接从jvm中取而不会走到redis层。常见的本地缓存可以利用guava cache或者caffeine实现。 优点 内存访问和redis访问的速度不在一个量级基于本地缓存接口性能好可以大大增加单实例的QPS 缺点 受应用内存限制容量有限 部分热点数据需要提前预知 热点数据自动检测有一定延迟 冗余存储备份key 通过空间换时间的思想将一个热key分解为多个不同的小key分别在redis集群的不同节点进行存储尽可能降低数据的倾斜 优点 不受应用内存限制轻松水平扩容 缺点 冗余多份存储浪费了redis部分内存 限流熔断兜底方案保护系统高可用 1基于nignx层限流 2基于应用网关限流 3基于微服务限流 常用的限流框架hystrix 和 sentinel 常用的限流算法漏桶、令牌桶、计数器统计、滑动窗口 六、Kafka如何保证消息幂等 1你做过的项目中是如何进行系统间解耦的 答系统之间基本都是通过kafka消息来实现解耦的kafka除了用于系统的解耦还能解决流量的削峰高并发的时候可以极大减轻数据库的压力。 2上游因为网络抖动同一条消息发送了两次这个时候可能会产生一些脏数据 答对于消息的幂等有很多种方案常见的解决方案有四种 1给业务设置唯一key比如订单业务的订单号、支付业务的支付流水号等常见的唯一key下游针对key加一个分布式锁最后通过数据库表设置唯一健兜底来保证消息的幂等。 2发送消息的时候构造一个全局的唯一Id下游消费的时候判断全局的唯一Id是否存在如果已经存在这条消息不用处理。 3对于有状态流转的业务如果状态机已经处于下一个状态这时候来了一个上一个状态的变更消息这个消息不用处理。 4对于一些更新的业务可以采用基于版本号的乐观锁更新SQL的时候我们判断传入的当前的版本号与数据库表的版本号是否相等如果相等更新成功不相等更新失败。 幂等的基本概念 查询操作天然幂等 查询一次和查询多次在数据不变的情况下查询结果是一样的。查询是天然的幂等操作。 删除操作天然幂等 删除操作也是幂等的删除一次和删除多次都是把数据删除(注意可能返回结果不一样删除的数据不存在返回0删除的数据多条返回结果多个)。 新增操作 新增操作这种情况下多次请求可能会产生重复数据 修改操作 修改操作如果只是单纯的更新数据比如update account set money100 where id1是没有问题的。如果还有计算比如update account set moneymoney100 where id1这种情况下多次请求可能会导致数据错误。 产生消息重复的原因 发送时消息重复 当一条消息已被成功发送到服务端并完成持久化此时出现了网络闪断或者生产者宕机导致服务端对生产者应答失败。 如果此时生产者Producer意识到消息发送失败并尝试再次发送消息消费者Consumer后续会收到两条内容相同的消息。 投递时消息重复 消息消费的场景下消息已投递到消费者Consumer并完成业务处理当消费者给服务端反馈应答的时候网络闪断。为了保证消息至少被消费一次消息队列的服务端将在网络恢复后再次尝试投递之前已被处理过的消息消费者Consumer后续会收到两条内容相同的消息。 负载均衡时消息重复 当消息队列的服务端或消费者重启、扩容或缩容时都有可能会触发rebalance此时消费者Consumer可能会收到重复消息。 解决方案 设置业务唯一key方案 1生产者消息体构造业务唯一key消息端针对这个key加分布式锁 2在消费端创建一个消息防重表利用插入记录唯一健约束控制 与业务有一定的耦合另外高并发下频繁对消息防重表进行操作性能比较低不太建议使用。 3数据库业务表加唯一索引数据库 设置全局唯一id方案 消息生产者生成一个唯一的消息Id利用分布式Id生成服务或本地Id生成一个Id我们在消息投递时给每条业务消息附加一个唯一的消息Id然后就可以在消费者利用类似分布式锁的机制实现唯一性的消费。 基于业务的状态机方案 在业务单据上面会有个状态状态在不同的情况下会发生变更一般情况下存在有限状态机当消费业务消息的时候如果状态机已经处于下一个状态这时候来了一个上一个状态的消息直接丢弃消息不处理保证了有限状态机的幂等。 基于version版本号的乐观锁方案 是适用于更新业务的场景更新表的时候通过版本号对比来保证消息的幂等 insert …on duplicate key update 更新方案 适合一些统计更新类的业务或者定时同步第三方平台数据到自己数据库的场景 七、Kafka消费积压百万数据 解决方案 消费端 1应用消费节点 kafka partition分区数可以扩应用消费节点否则扩应用消费节点没用应急优先扩节点 例如dance-member-service应用节点24个broker分区数16扩应用节点是否有用答案没用 dance-member-service应用节点12个broker分区数16扩应用节点是否有用答案有用扩4个节点消费能力明显增强 2优化消费端代码 . 自动提交改为手动提交 . 单条消费消息改为批量消费消息数据单条入库改为批量入库 . 消费逻辑涉及DB操作第一时间检查是否有慢SQL通过explain分析是否可以通过加索引解决大表要考虑是否会锁表尽可能低峰期操作 broker端 1kafka partition分区数 应用消费节点可以扩broker分区数否则扩broker分区数没用应急优先扩节点 例如dance-member-service应用节点12个broker分区数16扩broker分区数是否有用答案没用 dance-member-service应用节点24个broker分区数16扩broker分区数是否有用答案有用有8个应用节点处于空闲状态扩8个节点消费能力明显增强 生产端 1针对生产端采用动态配置开关降级关闭MQ生产系统不能快速扩容 2消费端消息没有积压后通过消息补偿程序对业务消息补偿同时消费端需要支持幂等 相关预案 1支持动态扩容 2配置开关动态关闭生产端 3配置开关动态关闭消费端 4生产端支持消息补偿 5消费端支持消息幂等 八、Kafka高性能设计 秒杀系统痛点 1高并发时间极短、 瞬间用户量大而且用户会在开始前不断刷新页面还会积累一大堆重复请求的问题请求过多把数据库打宕机了系统响应失败导致与这个系统耦合的系统也GG一挂挂一片 2链接暴露有人知道了你秒杀的url然后在秒杀开始前通过这个url传要传递的参数来进行购买操作。 3超卖你只有一百件商品由于是高并发的问题一起拿到了最后一件商品的信息都认为还有全卖出去了最终卖了一百十件仓库里根本没这么多货。 4恶意请求因为秒杀的价格比较低有人会用脚本来秒杀全给一个人买走了他再转卖或者同时以脚本操作多个账号一起秒杀。就是我们常见的黄牛党 5数据库一瞬间高QPS把数据库打宕机了谁都抢不到,活动失败GG这可能与高并发有重叠的点 解决方案 1高并发的解决方案 a. nginx做负载均衡一个tomcat可能只能抗住几百的的并发nginx还可以对一些恶意ip做限制 b. 资源静态化把前端的模板页面放到CDN服务器中放到别的服务器中减轻自己服务器的压力 c. 页面的按钮按一次后置灰X秒防止一直用户一直点,同一个用户重复点击虽然不会再卖给他但是请求还是会到后端给系统压力需要在前端按钮上做限制比如点一下限制五秒内不能点击。 d. 同一个uid限制访问频度做页面缓存x秒内到达站点层的请求均返回同一页面用来防止其他程序员跳过按钮直接用for循环不断发起http请求具体的话可以请求每次进来都去redis查有没有对应的id的key值没有就在redis中设置X秒过期的key e. 对于写请求用消息队列比如商品有一万件就放一万个请求进来当然要做好每秒几个的限制不能一秒内全放进来都成功了就继续放下一批没成功就剩下的请求全部返回失败 f. 读请求用redis集群顶住一个redis也只能顶住几万的并发叫上兄弟 g. 记住一定一定要先把数据库里的东西提前加载到redis来别等用户查了再加 2链接暴露的解决方案 ①页面中有一个计时模块是访问秒杀页面的时候去从服务器里拿的计时结束显示秒杀的按钮。 问题为什么不直接取用户的时间用户的本机时间是可以修改的。 ②点击秒杀按钮后再次请求服务器时间与秒杀的时间对比如果秒杀进行中返回一个由加密过的秒杀url 问题为什么还要再次请求服务器时间怎么加密url?,避免时间误差md5加密 ③通过这个加密过的url来进行支付、减库存操作。 3超卖问题的解决方案 我们假设现在商品只剩下一件了此时数据库中 num 1但有100个线程同时读取到了这个 num 1所以100个线程都开始减库存了。 每一个用户线程进来key值就减1等减到0的时候全部拒绝剩下的请求.所以一定不会出现超卖的现象 4恶意请求的解决方案 怎么限制让一个人只能秒杀一件商品秒杀成功将用户id存入redis集合。通过集合来判断 如果一个人用脚本掌握了多个账号去执行秒杀怎么办可以让用户付款的时候回答问题防止脚本的操作。比如12306买火车票的时候是不是会有按顺序点击图中相同的文字这就是为了防止脚本 5数据库层面的解决方案 用消息队列来削峰 用缓存来顶住大量的查询请求 九、Kafka消息如何保证不丢失 kafka是一个分布式的消息中间件它是基于磁盘做的数据存储具备高性能、高吞吐量低延时的特点其吞吐量轻松达到几十万它在IO和计算方面做了非常的优化工作。 高性能 顺序读写磁盘 充分利用操作系统页缓存 零拷贝 对消息批量读写 对消息批量压缩 分区分段加索引 生产者 丢失原因 1、kafka生产端异步发送消息后不管broker是否响应立即返回伪代码producer.send(msg)由于网络抖动导致消息压根就没有发送到broker端。 2、kafka生产端发送消息超出大小限制broker端接到以后没法进行存储。 解决方案 1、生产者调用异步回调消息。伪代码如下producer.send(msgcallback) 2、生产者增加消息确认机制设置生产者参数acks all。partition的leader副本接收到消息等待所有的follower副本都同步到了消息之后才认为本次生产者发送消息成功了。 3、生产者设置重试次数。比如retries3增加重试次数以保证消息的不丢失 4、定义本地消息日志表定时任务扫描这个表自动补偿做好监控告警。 5、后台提供一个补偿消息的工具可以手工补偿。 MQ broker: 丢失原因 kafka broker集群接收到数据后会将数据进行持久化存储到磁盘消息都是先写入到页缓存然后由操作 系统负责具体的刷盘任务或者使用fsync强制刷盘如果此时Broker宕机且选举了一个落后leader副本很多的follower 副本成为新的leader副本那么落后的消息数据就会丢失。 解决方案 1、同步刷盘不太建议。同步刷盘可以提高消息的可靠性防止由于机器掉电等异常造成处于页缓存而没有及时写入磁盘的消息丢失。但是会严重影响性能。 2、利用partition的多副本机制(建议) unclean.leader.election.enablefalse。数据丢失太多的副本不能选举为leader副本防止落后太多的消息数据而引起丢失。 replication.factor 3。消息分区的副本个数这个值建议设为3。 min.insync.replicas1。消息写入多少副本才算已提交这个值必须大于1这个是要求一个leader 至少感知到有至少一个 follower还跟自己保持联系。 replication.factormin.insync.replicas。这样消息才能保存成功。 消费者 丢失原因 1、消费者配置了offset自动提交参数。enable.auto.committrue。 2、消息者收到了消息进行了自动提交offsetkafka以为消费者已经消费了这个消息但其实刚准备处理这个消息还没处理完成消费者自己挂了此时这条消息就会丢失。 3、多线程消费消息某个线程处理消息出现异常还是会出现自动提交offset。 解决方案 1、消费者关闭自动提交采用手动提交offset。通过配置参数enable.auto.commitfalse关闭自动提交offset在完成业务逻辑以后手动提交offset这样就不会丢失数据。 2、消费者多线程处理业务逻辑等待所有线程处理完成以后才手工提交offset。 3、消费者消费消息需要进行幂等处理防止重复消费。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84649.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!