如何控制并发呢?可以使用redission的信号量 。key为数据库id:
RedissonClient redissonClient = Redisson.create(config);
RSemaphore rSemaphore = redissonClient.getSemaphore("semaphore");
// 设置1个并发度
rSemaphore.trySetPermits(1);
rSemaphore.tryAcquire();//申请加锁,非阻塞 。
由任务负责定期轮训 , 抢到名额后,就开始执行任务 。将该任务状态置为Process,任务完成后或失败后,释放信号量 。

文章插图
但是使用信号量限流有个问题,如果任务忘记释放信号量,或者进程Crash无法释放信号量,如何处理呢?可以考虑给信号量增加一个超时时间 。那么如果任务执行过长,导致提前释放信号量,另一个客户单争抢到信号量 , 导致 两个客户端同时写一个任务如何处理呢?
what,明明是将10亿数据导入数据库,怎么变成分布式锁超时的类似问题?
实际上 Redisson的信号量并没有很好的办法解决信号量超时问题,正常思维:如果任务执行过长,导致信号量被释放,解决这个问题只需要续约就可以了,任务在执行中,只要发现信号量快过期了,就续约一段时间,始终保持信号量不过期 。但是 Redission并没有提供信号量续约的能力,怎么办?
不妨换个思路,我们一直在尝试让多个节点争抢信号量,进而限制并发度 。可以试试选取一个主节点,通过主节点轮训任务表 。分三种情况:
情况1:当前执行中数量小于并发度
- 则选取id最小的待执行任务,状态置为进行中,通知发布消息 。
- 消费到消息的进程,申请分布式锁,开始处理任务 。处理完成释放锁 。借助于Redission分布式锁续约,保证任务完成前,锁不会超时 。
- 主节点尝试 get 进行中任务是否有锁 。
- 如果没有锁,说明有任务执行失败,此时应该重新发布任务 。如果有锁,说明有任务正在执行中 。
- 上报异常情况,报警,人工介入 。
那么主节点应该如何选取呢?可以通过Zookeeper+curator 选取主节点 。可靠性比较高 。
10亿条数据插入数据库的时间影响因素非常多 。包括数据库磁盘类型、性能 。数据库分库数量如果能切分1000个库当然性能更快 , 要根据线上实际情况决策分库和分表数量,这极大程度决定了写入的速率 。最后数据库批量插入的阈值也不是一成不变的,需要不断测试调整,以求得最佳的性能 。可以按照100,1000,10000等不断尝试批量插入的最佳阈值 。
总结
最后总结一下几点重要的:
- 要首先确认约束条件,才能设计方案 。确定面试官主要想问的方向,例如1T文件如何切割为小文件,虽是难点,然而可能不是面试官想考察的问题 。
- 从数据规模看,需要分库分表,大致确定分表的规模 。
- 从单库的写入瓶颈分析,判断需要进行分库 。
- 考虑到磁盘对并发写的支持力度不同,同一个库多个表写入的并发需要限制 。并且支持动态调整,方便在线上环境调试出最优值 。
- MySQL innodb、myisam 存储引擎对写入性能支持不同,也要在线上对比验证
- 数据库批量插入的最佳阈值需要反复测试得出 。
- 由于存在并发度限制,所以基于Kafka分离读取任务和写入任务比较困难 。所以合并读取任务和写入任务 。
- 需要Redis记录任务执行的进度 。任务失败后,重新导入时,记录进度,可避免数据重复问题 。
推荐阅读
- 搜索引擎如何判定网站的价值
- 揭秘CSRF攻击:如何防范,增强网站安全性
- TikTok全托管模式是什么?如何解读新模式
- 抖音话题头像怎么设置?抖音话题简介描述介绍如何修改?
- TikTok如何选品?打造爆款不是梦
- 如何发视频赚钱呢?手把手教你做
- 紫砂壶泡茶味道如何
- 如何做麻油鸡,放冰箱的麻油鸡加热要先切块吗??
- 能如何看电脑配置,如何查看自己电脑的配置信息
- 电脑扩展屏幕能如何操作,电脑桌面只在屏幕中间的位置显示怎么办
