- 博客(103)
- 收藏
- 关注
原创 关于推荐场景的一些思考
背景由于用户数的飙升,推荐使用的技术栈也在不断升级,以满足更高并发和更大数据量的推荐场景。推荐相关的原始数据从小几十万到几百万,到几千万,再到上亿。推荐1.0从全库的用户数据中load出满足条件的用户,在jvm做计算,得到推荐结果。随着用户数量的上升,满足条件的用户越来越多,导致计算量越来越大,性能逐渐变低推荐2.0一边从数据库中load出满足条件的用户,一边用sql在数据库做计算,直接得到推荐结果。利用索引,性能提升五倍左右。随着用户量继续上升,性能也在逐渐变低。推荐3.0将数据库推荐相
2022-04-26 14:04:52 2399
原创 canal同步造成网络阻塞
背景发现一个实例的推荐请求比另外一个实例慢10+倍。分析通过各种监控工具,最终发现慢的实例执行着canal同步消息,并且更新到es。结论canal更新频繁造成网络IO开销大,数据准备和发送的时间加长。因此,如果使用canal做数据 同步,建议使用独立的服务做这件事,避免彼此影响,造成性能下降以及同步延迟加大。...
2022-04-08 10:29:08 3126
原创 数据库慢查询导致接口大面积性能下降
背景从监控pinpoint中看到业务高峰期,接口响应时间呈现一柱擎天的姿势。分析数据库监控cpu打满、内存使用了80%,数据库连接使用了80左右,配置了800,存在大量空闲。查看慢sql日志,发现慢sql数量飙升。接口监控大量接口在getConnection()时消耗了大部分时间。查看数据库连接配置发现数据库配置了最大20的连接数。超时时间20s。原因慢sql导致大量请求阻塞在获取druid连接资源上。解决方案增加数据库配置,调整成8c16g。因为调整了最大连接数,数据库压力可
2022-04-07 19:03:38 2241
原创 ArrayBlockingQueue源码阅读
允许多生产消费者使用队列JDK注释中的生产消费者代码,允许有多个生产者和多个消费者。class Producer implements Runnable { private final BlockingQueue queue; Producer(BlockingQueue q) { queue = q; } public void run() { try { while (true) { queue.put(produce()); } } catch
2022-02-17 15:56:26 169
原创 趣聊线程池ThreadPoolExecutor
问题咱们先聊三个问题,带着问题看源码:线程池如何保持核心线程不消亡?如果核心线程数量为0,新的任务先入队还是直接运行?最终线程池是否会走向消亡?允许核心线程超时,影响点在哪?.示例自定义线程池class MyThreadPool extends ThreadPoolExecutor { public MyThreadPool(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
2022-02-17 14:49:18 1221
原创 数据交互的两种模式对比-push和pull
数据交互模式push模式服务端主动给客户端推消息的。优点:消息及时到达。缺点:无法感知客户端的消费能力,可能造成客户端消息堆积。pull模式客户端主动从服务端拉取消息。优点:客户端不存在消息堆积的情况。缺点:消息处理不及时,可能存在大量无效请求,客户端需要考虑拉取频率逻辑。polling、long polling轮询和长轮询是pull模式的两种实现方式。**polling:**客户端定时从服务端拉取消息,无论是否有消息,都立即返回。因此存在大量的无效请求。**long polling
2022-01-25 14:36:23 3775
原创 function_score组合script_score定制评分结果
背景ES版本:6.4脚本分两步:过滤掉不关心的数据,加速后续计算分值性能编写分值脚本,得到最终分值GET /user/_doc/_search{ "query": { "function_score": { // 过滤掉不关心的数据,加速计算分值性能 "query": { "bool": { "filter": [ { "term": {
2022-01-06 16:03:30 1007
原创 使用ES做推荐需求
背景推荐算法涉及的数据范围多,而且来源于不同的表。如果基于mysql去做推荐需求,很快会遇到性能瓶颈。说到底,基于mysql构建的数据模型,适合普通的业务需求,而推荐需求,需要寻找新的数据模型。因此,引入ES,构建新的数据模型,性能提升5-10倍。新数据模型架构图通过canal监听mysql数据库相关表的变化,将变更发送给MQ,消费者消费MQ,将变更更新到ES。使用HightLevel Client,结合计分脚本painless做推荐业务。基于开闭原则,封装相关模块,使得易拓展。...
2022-01-05 14:32:09 2049
原创 Redis的线程模型
Redis线程模型Redis基于Reactor模式开发了网络事件处理器,这个处理器被称为文件事件处理器(file event handler)。它的组成结构为4部分:多个套接字、IO多路复用程序、文件事件分派器、事件处理器。因为文件事件分派器队列的消费是单线程的,所以Redis才叫单线程模型。文件事件处理器使用 I/O 多路复用(multiplexing)程序来同时监听多个套接字, 并根据套接字目前执行的任务来为套接字关联不同的事件处理器。当被监听的套接字准备好执行连接应答(accept)、读取(
2021-12-31 15:13:54 136
原创 Redis底层数据结构
Redis常用数据类型Redis常用数据类型包括:String、Hash、List、Set、ZSetredis的数据模型dictEntry在一些编程语言中,键值对的数据结构被称为字典,而在 Redis 中,会给每一个 key-value 键值对分配一个字典实体,就是“dicEntry”。dicEntry 包含三部分: key 的指针、val 的指针、next 指针,next 指针指向下一个 dicteEntry 形成链表,这个 next 指针可以将多个哈希值相同的键值对链接在一起,通过链地址法来解决
2021-12-30 22:53:13 1226
原创 mysql之sql优化实践汇总
概述未来的SQL优化实践汇总都总结在本文。使用limit对索引优化其中priTmplId 模板ID为索引,不唯一,但是关联的openId唯一explain update wx_subscribe_user set sendTimes = sendTimes + 1 where openId = "oT10x5Gkfb5R-3HZ1Vb1KAlPoq2M" and priTmplId = "hEVQfvr-S2PlJp7SxqZT7ijc3l_xMnvIAiUozcvUgyq"执行计划type
2021-12-28 11:11:05 757
原创 Dubbo2的协议对比
dubbo2.x支持的协议dubbo 协议rest协议http 协议hessian 协议redis 协议thrift 协议gRPC 协议memcached 协议rmi 协议webservice 协议下面列举几个说明dubbo协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。反之,Dubbo 缺省协议不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。特性连接个数:单连接连接方式:长连接传输
2021-12-11 10:53:58 235
原创 一文理解zookeeper的强大之处
zookeeper在分布式中的地位在分布式组件中,比如redis、kafaka,都能看到zookeeper思想。可以认为,zk在分布式这一块是非常成功的。分布式系统相关理论zookeeper的本质zk最核心的,是在集群高并发环境中,使用zab协议保证节点数据的最终一致性,可用于服务发现,分布式锁,分布式领导选举,配置管理等。zk的一次数据写入过程本质上是一次2PC提交的过程。zookeeper数据结构zk是树状结构,有唯一一个根结点。zk数据节点如何保证安全使用zab协议保证数据节点安全。z
2021-12-11 00:57:37 188
原创 分布式系统理论
CAP理论聊到分布式,必定绕不开CAP理论。CAP理论认为,一个分布式系统,最多可以满足其中的两项,这就意味着需要牺牲第三项。其中P是必须要满足的,否则可能单点故障导致整个分布式系统不可用状态,所以每个服务要做冗余部署。所以需要在A和C做取舍。如果选择A,意味着每次数据更新需要做同步到冗余节点,此时系统无法马上获取最新数据。如果要马上获取最新数据,只能晚点再同步数据到冗余节点。C:一致性:指强一致性,更新操作成功后,所有节点在同一时间的数据是一致的。A:可用性:服务一直可用。P:分区容错性:分布式系
2021-12-11 00:54:41 159
原创 zookeeper的ZAB协议
概念ZAB(ZooKeeper Atomic Broadcast,原子广播协议),解决zk的奔溃恢复和主从数据同步问题。集群的三种角色Zookeeper 集群是一个基于主从复制的高可用集群,每个服务器承担如下三种角色中的一种Leader一个 Zookeeper 集群同一时间只会有一个实际工作的 Leader,它会发起并维护与各 Follwer 及 Observer 间的心跳。所有的写操作必须要通过 Leader 完成再由 Leader 将写操作广播给其它服务器。只要有超过半数节点(不包括 ob
2021-12-11 00:53:07 226
原创 记录一次dubbo连接资源耗尽事故
异常信息Server side(172.24.0.20,9090) thread pool is exhausted, detail msg:Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-172.24.0.20:9090, Pool Size: 500 (active: 500, core: 500, max: 500, largest: 500), Task: 546 (completed: 46), Executor statu
2021-12-09 12:10:24 1331
原创 dubbo2对传输数据大小限制引起的异常
背景在做数据导入时,服务器报以下异常:Caused by: org.apache.dubbo.remoting.transport.ExceedPayloadLimitException: Data length too large: 10794838, max payload: 8388608, channel: NettyChannel [channel=[id: 0x5aa64030, L:/172.31.8.190:51674 - R:/172.31.9.63:9090]] at
2021-12-08 10:58:34 2426
原创 设计模式之静态代理和动态代理
定义本质是对目标方法的增强,允许代理类在执行目标方法时,做些自己的事来增强目标方法。静态代理如果知道被代理类的具体职责,可以使用静态代理。如果不清楚被代理类是谁,只能只用动态代理。这是静态代理和动态代理的区别,即是否清楚被代理对象是谁。UML代理类和被代理类同时实现Movable接口,此时,除了可以增强Tank对象外,还允许对代理对象做增强,实现代理和代理之间的互相嵌套。是不是很像装饰者模式?其实有些设计模式本身就没有清晰的边界。代码UML图已经很清晰了,写点核心代码,体会这个UML的精髓。
2021-12-07 00:17:18 201
原创 设计模式之模版方法
定义父类(抽象类)定义了方法的执行步骤,但是不定义具体的执行逻辑,由子类决定父类的行为。UML类图代码抽象类定义玩的动作,分初始化游戏、开始游戏、结束游戏。但是没有定义其中的具体执行细节。public abstract class Game { abstract void initialize(); abstract void startPlay(); abstract void endPlay(); //模板 public final void play(){
2021-12-06 23:00:26 2360
原创 设计模式之迭代器模式
定义这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。本质上是定义了A类对象具备共同的行为,比如访问下一个元素、移除一个元素等。具体的行为由具体的A对象决定。UML容器接口支持获取迭代器,在子类中定义迭代逻辑。代码统一的迭代器接口,定义迭代器应该具备哪些能力public interface Iterator { public boolean hasNext(); public Object next();}统一的容器接口,定义拥有迭代器的能力。public
2021-12-06 05:19:36 83
原创 设计模式之观察者模式
定义定义事件和处理逻辑的一对多关系。当监听到某个事件发生时,通知具体的处理逻辑。UMLsubject注册了待通知的对象,调用内部的notifyAllObservers方法,表示触发了相关的事件,通知List集合对象。代码public class Subject { private List<Observer> observers = new ArrayList<Observer>(); private int state; pu
2021-12-06 04:57:48 70
原创 设计模式之责任链模式
定义为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。示例前端传入一个字符串,后端需要对字符串做过滤,但是目前我不知道要过滤哪些东西,意味着未来会拓展更多的过滤方式。比如,第一步过滤script脚本、第二步过滤敏感词等。// 部分人的处理方式if(存在script脚本) doSomething
2021-12-06 04:36:06 284
原创 设计模式之装饰器模式
概念装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。和继承的区别一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很多。比如:我有一个轮子,有滚动的功能。现在,我想把它装在汽车上,有驾驶的功能。我想让我的汽车是红色的。这时候使用继承实现的话没问题,但是如果有一天我想要一个红色的轮子,把它装在汽车上,有驾驶的功能,汽车要蓝色的。这时候
2021-12-06 03:45:02 441
原创 设计模式之门面模式
为什么要门面模式客户端连接系统时,如果一个客户端需要对接的子系统太多,就会导致调用链路错综复杂,这时候如果可以隐藏系统的调用关系,把功能交给一个单独的系统去完成,这样就会干净得多。缺点:client和服务方的调用链路关系强绑定,如果服务方需要做服务迁移或者相关优化,需要牵动client开发人员一起动。门面模式客户端只跟facade打交道,如果需要什么功能,可以直接告诉接待员,接待员负责实现逻辑细节。优点:client不关心一个功能在服务端是怎么流转的,解耦客户端和服务端。如果服务端需要做优化,c
2021-12-05 16:19:45 305
原创 设计模式之工厂模式
本质任何可以产生对象的方法或者类,都是工厂模式。为什么有了new后,还要工厂灵活控制生产过程。比如,创建对象前后需要做统一日志处理,创建前需要校验调用方的权限等。简单工厂一种简答的工厂设计模式,专门生产一类产品。优点: 针对一类商品的扩展简单,只需要添加子类以及在工厂中添加创建子类过程。缺点:生产的对象属于一类产品,如果要跨类别生产,只能重新写另外一个工厂类。抽象工厂本质上是简单工厂的工厂。支持生产多类产品(多个产品镞),允许跨产品类型创建产品。优点:当一个产品族(某一类产品)中的
2021-12-05 15:48:56 255
原创 设计模式之单例模式
定义一个类的实例最多只有一个。代码单例模式网上有七八种,但不全是线程安全的,工作中最常用的,往往是饿汉式。spring的IOC容器的实例默认也是单例的,而且是懒汉式的。最简单的单例饿汉式,类加载的时候完成单例的初始化public class Singleton { private Singleton() {} private static Singleton single=new Singleton(); //静态工厂方法 public static Singl
2021-12-05 12:53:53 78
原创 实用设计模式之对设计模式的理解
本质设计模式本质上是完成一件事的套路,目的是使得代码更健壮、更符合开闭原则。无论何种设计模式,都没有完全统一的范式,真正核心的是这个设计模式达到目的的思路。同一种设计模式,达到目的的方式不止一种,但是思路是一样的。因此,可以认为,设计模式的核心是它的思路。...
2021-12-05 12:35:43 100
原创 实用设计模式之策略模式
定义策略模式本质上是允许使用不同的方式去做一类事情,比如:使用不同的排序算法去做排序、使用不同的匹配算法去做匹配。歧义网上有说策略模式取代了原来需要用if、swich做的事情,这样说没问题,但是不等于原来if、swich做的事情都适合用策略模式,因为策略模式意味着需要创建定义统一接口和更多子类,如果if逻辑本身就很简单,还想使用策略模式,这就得不偿失了。UML类图代码示例class Client { public static void main(String[] args) {
2021-12-05 12:29:55 130
原创 计算机网络之HTTP和HTTPS
HTTPhttp全名超文本传输协议,允许客户端和服务端通信。HTTP1.0基于TCP、短链接,每次请求都需要关闭当前连接,下次请求时需要再次经历三次握手过程,半双工协议。不允许服务端主动给客户端发请求,只允许服务端响应客户端请求。HTTP1.1基于TCP、keep-alive默认为true,建立一次连接后,连接会存在一段时间,在这段时间内通信,不需要再次经历三次握手过程,即多次请求复用一个TCP连接。半双工协议。不允许服务端主动给客户端发请求,只允许服务端响应客户端请求。不应该把keep-aliv
2021-12-04 01:47:03 3289
原创 dubbo服务线上问题排查调试技巧
在线上调用dubbo服务有时候发现线上BUG的时候,想要在线上环境复现这个bug,除了使用arthars帮助定位问题外,还可以手动调用dubbo服务复现BUG。进入dubbo提供方服务,需要dubbo服务提供方的ip和端口,端口通常为9090telnet ip port查看服务提供方有哪些服务ls查看某个服务有哪些子方法ls serviceName调试服务提供方某个方法invoke classPath.methodName...
2021-12-03 17:26:47 274
原创 BIO和NIO比较
同步单线程模型(BIO)创建socket和处理请求在一个线程完成。问题:请求处理慢,后续请求需要等待前面的请求处理完成后才被处理。容易把内核的pending queue打满,造成后续请求自动被系统拒绝。同步多线程模型(BIO)派发线程不再独自完成创建socket和处理请求的任务。派发线程接收到一个socket后,马上将socket交给一个工作线程去完成,由工作线程去内核完成socket的读写操作。这种模型下,扛住大几千上万并发不是问题。问题:由工作线程处理read/write操作,占用
2021-12-03 00:21:20 1203
原创 计算机网络之UDP协议
本质协议简单,搭建在IP协议之上尽可能的减少通信机制,允许用户直接发送报文的情况下最大限度的简化应用的设计,速度非常快目的为了更快传输,发送报文,无法拆分数据(因为无序,拆分可能导致报文不可用)概念在传输层提供直接发送报文(Datagram)的能力。Datagram是数据传输的最小单位。为什么不直接用IP协议传输报文IP协议只能吧数据从一个网络接口发送到另一个网络接口,无法寻址到应用。封包格式从封包格式可以看出,UDP头比TCP头简单很多,并且客户端不需要等待ACK确认,服务端不需要按
2021-12-02 08:31:25 1319
原创 计算机网络之IP协议
IP协议可能遇到的问题封包损坏丢包重发乱序网络层需要解决的问题延迟、吞吐量、丢包率无法同时满足。允许设置Type Of Service字段,表示哪个优先。IP协议工作原理主要有下面五个过程:分片为了适配底层网络,有时候需要对IP数据段做分片处理。协议头Type Of Service:服务的类型,是为了响应不同的用户诉求,用来选择延迟、吞吐量和丢包率之间的关系。IHL(Internet Header Length):IP协议头的大小。Total Length:报文(封
2021-12-01 00:14:09 242
原创 计算机网络之五层模型
五层模型为什么不用OSI七层模型?删除了会话层,会话是虚拟概念,不是必须的删除了表示层,数据压缩、数据格式转换不是应用必须的TCP/IP协议群传输层:TCP协议、UDP协议、TLS/SSL、SCTP等网络层:IP协议(ipv4和ipv6)、ICMP协议、IPSec协议...
2021-11-30 23:45:12 1030
原创 计算机网络之TCP
TCPTCP全名是(Transport Control Protocol),是一个可以提供可靠的、支持全双工、连接导向的协议,因此在客户端和服务端之间传输数据的时候,是必须先建立一个连接的。怎么理解连接是虚拟、抽象的概念,由客户端和服务端程序控制能让两个通信的程序间确保彼此都在线加快响应请求速度连接也被称为会话(Session)使通信更稳定、安全消耗更多资源怎么理解全双工单工:任何时刻数据只能单向发送半双工:允许数据在两个方向上传输,在某一时刻,只允许数据在一个方向上传输全双工:
2021-11-30 23:40:41 3271
原创 排序算法总结
选择排序选择最小/最大元素放在最终位置。从0 ~ n-1 找到最小值位置,和最左边位置交换。从0 ~ n-2 找到最小值位置,和最左边位置交换。从0 ~ n-3 找到最小值位置,和最左边位置交换。从i ~ n-1-i 找到最小值位置,和最左边位置交换。public static void selectionSort(int[] arr){ if (arr == null || arr.length == 1) { return arr; } f
2021-11-30 06:10:39 113
原创 elasticsearch-集群处理不同请求
ES集群ES集群启动后,不允许拓展主分片的数量,但是可以任意拓展副分片数量。这就意味着我们在增加机器的时候,可以很方便的横向拓展ES副本分片。ES集群扩容过程以及分片的分布单节点在硬件故障时有丢失数据的风险。拓展节点两个节点时,通过配置,为每个分片分片一个副本,并且ES保证尽可能将分片分配到不同节点,最大程度保证数据安全。其中P表示主分片,R表示副本分片。进一步水平扩容,每个节点的分片数量开始变得松散,这也就意味着,主分片和副本一定的情况下,存在最大可扩容节点。随着节点的增加,每个分片可存
2021-11-05 19:21:07 338
原创 elasticsearch-倒排索引
倒排索引倒排索引是ES核心数据结构之一。试想这样一个场景。我给不同的用户打标签,最终我需要根据标签找到哪些用户包含这些标签。如果使用关系型数据库存储用户标签信息,我需要遍历每一个用户,最终得到想要的结果。ES使用倒排索引的数据结构,只需要一次,就可以得到结果。数据结构Term就是我的标签名,后面跟着包含这个标签的用户信息。我只需要找到对应标签,所有包含该标签的用户信息都可以一次得到。倒排索引的不足如果我要找到某个用户的所有标签信息,倒排索引就显得吃力了。我需要遍历每个标签,看看是否包含这个用
2021-11-05 17:56:36 1079
原创 善用业务监控工具
背景偶然看到一个核心业务功能在监控中响应时间很长,接近10s。但是在其它时间段发现响应时间很快,200ms左右。原因通过数据库监控发现,在中午12:00到12:10这个时间段内,数据库的流量、查询数、插入数、cpu、内存等指标都出现不同程度的飙升。但是除了流量外,其它数据虽然飙升,但还在正常区间内。初步判断是网络带宽不够导致了业务性能变慢。验证查看接口监控通过PINPOINT查看这个接口在不同时间的响应时间,发现每天都会有这个现象。查看其它接口监控信息通过监控工具查看其它核心接口的性能,发现
2021-11-01 16:22:01 95
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人