布隆过滤器
- 传统布隆过滤器由一个初始全为 0 的位数组和多个独立的哈希函数组成。添加元素时,会通过多个哈希函数将元素映射为位数组中的多个位置,再把这些位置标记为 1;查询元素时,同样用这几个哈希函数得到对应位置,若所有位置均为 1,则元素 “可能存在”,若有任一位置为 0,则元素 “一定不存在”。不过它存在局限性,元素增多会让误判率升高,且无法扩容,同时因位数组的位置可能被多个元素共享,无法删除单个元素。
- TairBloom 为解决传统布隆过滤器的扩容问题,采用 Scalable Bloom Filter 设计。当当前布隆过滤器中的元素达到预设容量,误判率即将超出阈值时,它不会修改原有过滤器,而是创建一个新的布隆过滤器,将多个过滤器组合使用。新过滤器的容量默认是上一层的 2 倍,且始终维持初始设定的误判率。查询时从最新的过滤器开始遍历检查,直到所有层级检查完毕,以此保证在数据量增长时,误判率依然稳定。
- 黑名单,海量用户活动推送去重(防止多推)
nlb和slb
-
slb7层,可以根据http/https协议,url,域名,cookie等信息进行请求分发,毫秒级。可以配合nginx使用,也可以不配合 ```aiignore server { listen 80; server_name tag-platform-web-test.tag-platform-test.paas.test;
location /api/meta/ { proxy_pass http://service-a-cluster/; }
location /api/user/ { proxy_pass http://service-b-cluster/; } }
* nlb4层,根据tcp/udp连接进行分发(ip地址和端口),延迟低,微妙级别。可以配合nginx使用(nlb将流量发到nginx机群,nginx来路由),也可以不配合。
```aiignore
nlb服务发现处理,1.预置后端列表(手动配置后端服务ip,健康检查剔除故障节点),2.动态发现后端(如k8s自动同步服务实例列表,利用k8s的selector字段字段关联pod,k8s自动将匹配pod的ip注册为nlb后端,无需手动配置ip)
apiVersion: v1
kind: Service
metadata:
name: my-service
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: my-app
kafka和rocketmq区别【从协议说就行】
- https://www.bilibili.com/video/BV1m7421Z7fN/?spm_id_from=333.337.search-card.all.click&vd_source=d163c2ddcb7dcb1c2df5a0b53416de2b
- partition 是完整消息,queue是offset对commitlog的索引
- rmq是架构的减法,功能的加法,zk重换成nameserver,后来kafka也意识到zk重,去掉换成kraft算法(kraft使用拉模型,raft算法是推模式)
- kafka写partition就是写下面的segment,但是多个topic对应多个segment文件,同时写多个topic,每个segment内部是顺序写,但是 segemnt在磁盘位置不同,此时就不一定是顺序写了。但是rmq是一个文件的顺序写
- 简化备份模型, partition存在不同broker下,并对partition配置副本(比如partition1和partition2存在broker1,但是partition1的副本存在broker2上,partition1分为leader和fllower),主从partition进行数据同步,其实就是同步segment 。rmq直接同步commitlog文件
- rmq支持tag ,事物,延迟,死信
- 零拷贝https://www.bilibili.com/video/BV1Zy411e7qY?spm_id_from=333.788.videopod.sections&vd_source=d163c2ddcb7dcb1c2df5a0b53416de2b rmq通过mmap能获取到消息内容,但是sendfile获取不到,所以rmq没有用sendfile。因为sendfile比mmap更少的拷贝次数,所以kafka更快
datax原理
https://blog.51cto.com/u_15294985/5147819 启动job,拆分task,根据预设的并发数量/5计算启动多少个taskgroup。之后taskgroup管理task,每个task用reader读取数据放channel,writer从channel取数据去写 代码在core里面Engine.entry,检查配置,之后就是container.start启动。两个实现,job和taskgroup

- split先拆分,但是拆分之前需要先找到并发数,有record条数级别,byte级别,channel级别。前面2个级别的数据取最小值,channel优先级最低
线程池怎么设置的大小,这么设计的依据是什么?
- 目的是削峰,那也可以用mq,功能更全
- 动态线程池(调用原生方法修改,可以保证线程安全 )
- 一个java应用可以设置很多线程,取决于用户级别限制(1w+),还取决于线程栈内存Xss限制(最大线程数 ≈ (系统可用内存 - JVM堆内存 - 其他进程内存) / 单个线程栈大小)
flink原理
- 有状态的实时流计算(状态是为了存储流节点的中间计算结果,另外状态的保存有助于容错恢复 ),checkpoint可以把状态进行快照存储
- flink-架构,14精准一次,15反压(分布式阻塞队列),16倾斜,20去重,39面试基础,40进阶,41选型,水印(乱序问题)
- 精准一次
- 定期拍 “快照”(Checkpoint) 就像玩游戏时定期存档。Flink 会每隔一段时间,把所有计算到一半的状态(比如统计了多少订单、窗口里有哪些数据)拍个 “快照”,存到安全的地方(比如硬盘、分布式存储)。 万一程序崩溃了,不用从头再来,直接读最近的快照恢复状态,接着往下算。 这一步保证了 “就算出错,也能回到正确的进度”,不会重复算之前算过的内容。
- 状态 “随身带”(状态后端) 计算过程中产生的临时数据(比如累加的计数、缓存的中间结果),不会随便丢在内存里,而是存在专门的 “保险箱”(状态后端,比如 RocksDB)里,还会同步到快照里。 就算当前机器的内存崩了,“保险箱” 里的数据也丢不了,恢复快照时能完整拿回来。 这一步保证了 “中间数据不丢”,是精准计算的基础。
- 输出 “先存后发”(事务控制)
给外部系统(比如写 Kafka、数据库)发结果时,不直接发出去,而是先存在 “临时中转站”:
等快照拍完、确认没问题了,再正式提交,告诉外部系统 “这些结果可以用了”。
要是中间出错了,“中转站” 里的临时数据就直接扔了,外部系统根本看不到,不会重复收到。
总结
简单说就是:
快照(Checkpoint)→ 保证 “进度不丢,能恢复”;
状态后端 → 保证 “中间数据不丢,算得准”;
事务输出 → 保证 “结果只发一次,不多发”。
三者配合,不管过程中出多少岔子,最终结果都是 “不多不少,正好一次”。
flink+kafka的好处大于单纯kafka处理的原因(不丢,复杂实时计算【其实就是flink的特性】)
就像 “人工搬货” 和 “自动化流水线” 的区别,前者能干活,但效率、可靠性、复杂场景处理能力差很多。具体区别可以从三个核心维度看:
- 处理方式:“手动接货” vs “自动流水线”
用普通程序处理 Kafka:就像雇个工人守着 Kafka 的 “传送带”(分区),数据来了就手动接过来处理。 得自己写代码拉取数据(调用 Kafka Consumer API),处理完还要手动记录 “读到哪了”(Offset),万一程序崩了,没记 Offset 就会重复读或漏读。 处理逻辑简单(比如过滤、简单统计)还行,要是想做 “每 5 分钟统计一次”“关联多个数据源” 这种复杂操作,得自己写定时器、维护状态(比如缓存中间结果),很容易出错。 Flink + Kafka:像自动化流水线,Flink 自动从 Kafka 拉数据,内置了 Offset 管理、状态存储、窗口计算等 “机器”,你只需要告诉它 “怎么处理”(写算子逻辑),剩下的全自动化。 - 可靠性:“易丢易重” vs “稳如老狗”
普通程序的痛点: 数据可能丢:如果处理到一半程序崩了,没来得及提交 Offset,重启后可能从上次的位置重新读,导致重复处理;或者没存中间结果,之前算的全白费。 扛不住压力:如果 Kafka 数据突然暴涨,普通程序单线程处理不过来,容易堆积数据,甚至崩溃(比如内存撑爆)。 Flink 的保障: 不丢不重:通过 Checkpoint 自动存 Offset 和中间状态,崩了能精确恢复,数据既不丢也不重复算。 弹性抗压:数据多了就自动加 “工人”(并行实例),配合 Kafka 分区分散负载,再大的流量也能扛住。 - 复杂场景处理:“应付不了” vs “轻松拿捏”
普通程序搞不定的事: 乱序数据:Kafka 数据可能迟到(比如本该 10 点到的数据 10:05 才来),普通程序要么算早了漏数据,要么一直等没实时性,很难平衡。 状态依赖:比如 “统计用户累计消费”,需要一直记着每个用户的历史消费额,普通程序得自己用数据库或缓存存,读写麻烦还容易出并发问题。 多流关联:比如把 “订单流” 和 “物流流” 按订单号关联,普通程序得自己写逻辑缓存两个流的数据,匹配效率低还容易出错。 Flink 轻松解决: 水印机制:自动判断 “哪些时间的数据已经到齐”,乱序数据也能算得准。 内置状态管理:中间结果自动存在本地或分布式存储,安全又高效,不用自己折腾缓存。 丰富算子:直接用 join 算子关联多流,用 window 算子做时间窗口统计,一行代码搞定复杂逻辑。
http和rpc
https://www.bilibili.com/video/BV1Qv4y127B4/?spm_id_from=333.1387.upload.video_card.click&vd_source=d163c2ddcb7dcb1c2df5a0b53416de2b