Kafka架构设计
Kafka是一个消息队列。被大家用在分布式消息队列或者流数据处理场景。
有几个问题,大家不知道思考过没有?
1、Kafka有哪些组件,作用分别是什么,为什么这么设计?
2、Kafka是怎么保证高性能、高并发、高可用的呢?
Kafka是一个消息队列。被大家用在分布式消息队列或者流数据处理场景。
有几个问题,大家不知道思考过没有?
1、Kafka有哪些组件,作用分别是什么,为什么这么设计?
2、Kafka是怎么保证高性能、高并发、高可用的呢?
经常会遇到的一个问题是数据库如何保证不丢数据? 同样的Redis如何保证不丢数据?
MySQL里有 redo log、bin log、undo log
Redis包含 rdb log、aof log
在原来coding pages服务和github pages服务都可以免费试用时,在域名解析时配置 国内访问coding pages部署的博客静态文件,国外访问github pages部署的静态文件。国内国外访问速度都基本都在200ms内。
自从 coding.net 停止免费的pages服务后,只有github pages可以免费试用,国内访问博客只能访问github pages服务,导致访问速度很慢。被人吐槽了一次,所以想优化一下。
优化思路比较简单,
1、国内ip访问国内的博客服务 比如gitee pages服务
2、通过缓存加快访问速度 比如CDN缓存
在做系统稳定性-下游用户接口的兜底时,当时有2种方案:
第一种是只校验用户uid(18位数字 long类型 8字节)是否合法,这种方案实现简单,但有安全风险;
另一种方案是缓存一份用户信息(uid、城市、运营单元、收货地址id、身份 等) 数据,用户接口异常时用缓存数据校验,这种方案实现稍微复杂点,但是没有安全风险。
当时有2亿多用户,别的组的同学缓存过全量(20多个字段)用户数据,用了200G内存。 由于占用内存太多,收益不高,他们很快就放弃缓存用户数据了。
由于我们并不需要缓存用户的20多个字段,只需要缓存6个字段,想自己计算一下+实验下看需要多大内存,如果占用内存少可以使用方案二。
Redis的IO模型
[1] Pattern: Backends For Frontends
[2] 蚂蚁财富的BFF实战
[3] 美团-GraphQL及元数据驱动架构在后端BFF中的实践
[4] BFF实践(通过网关的服务编排功能)
[5] 了解BFF架构
[6] 微服务架构 BFF和网关是如何演化出来的
相比于 Go 语言宣扬的“用通讯的方式共享数据”,通过共享数据的方式来传递信息和协调线程运行的做法其实更加主流,毕竟大多数的现代编程语言,都是用后一种方式作为并发编程的解决方案的。
我们来了解一下go中的互斥锁sync.Mutex
sync.Mutex是go语言里的一种互斥锁,是保证同步的一种工具。
类似生活中去医院看病时挂号等医生叫号的过程,有很多患者挂号(协程),只有一个医生(资源),被叫号的患者(拿到锁)可以到诊室里让医生看病。看完病离开诊室(释放锁)。
先看一个例子
package main
import "sync"
var sum int = 0
var wg sync.WaitGroup
var mu sync.Mutex
// 开10个协程并发执行1000次 sum++
// 如果不加 mu.lock() mu.unlock() 最后的结果不是10000 一般会小于10000
// 把 // mu.lock() // mu.unlock() 前面的注释删除,结果就是10000
// 这个是缓存导致的可见性问题。
// 具体原因是因为sum++不是原子操作,CPU分2条指令执行,CPU执行第2条指令时获取到的缓存sum值和主内存sum值不一致导致
func main() {
// fatal error: sync: unlock of unlocked mutex
// // mu.Unlock()
// 开10个协程并发执行1000次 sum=sum+1
for i := 0; i < 10; i++ {
wg.Add(1)
go funcAdd()
}
// 等所有协程执行完
wg.Wait()
println("result:", sum)
}
func funcAdd() {
for i := 0; i < 1000; i++ {
// 对sum加锁
//mu.Lock()
sum++
// 对sum解锁
//mu.Unlock()
//println("result=", sum)
}
// 没有下面这一行代码 提示 fatal error: all goroutines are asleep - deadlock!
wg.Done()
}
上面的代码主要功能是开10个协程并发执行1000次 sum++,并打印结果,可以自己执行一下,会发现执行的结果<10000。
把第33行 36行前的注释删掉,程序执行的结果就是结果就是10000