当前位置:网站首页>日志中打印统计信息的方案
日志中打印统计信息的方案
2022-07-01 13:46:00 【zhanglehes】
概要
目前维护的一套c++服务,在打印日志时会存在锁竞争。先用brpc定位锁竞争的环节,然后提出集中改进方案,以及它们的优缺点。
contention火焰图
使用brpc在压测环境下打印contention火焰图。

左边的圆圈是处理服务的接入数据,会记录接收量,os类型,业务方类型等统计参数;
右边那两个稍小圆圈是两处发送下游,会记录发出量等统计参数;
它们都是用同一把锁,当需要写入统计数据时,会去竞争这把锁;
从连接方框的边旁的数据大小,可以看到主要的锁竞争来自于处理接收数据的业务函数。原因是我们的服务接收数据是逐条接收的,但是发送数据是批量,因此数量是不对等的。
改进方案
每个统计指标对应一把锁
好处:锁的作用域得到最小力度的控制
坏处:当有多处需要写入的统计信息量较大时,这种场景不合适
自旋锁
好处:不会发生cs
坏处:当临界区较长时,对cpu的浪费不能忽视
使用atomic
好处:基础类型在x86架构上是无锁的
坏处:atomic变量虽然比加锁赋值更轻量,但比普通参数复制还是更重一些。当统计参数较多时,这部分时间开销累计起来也是很大的
对比atomic和加锁的时间开销
atomic
#include<iostream>
#include<atomic>
#include<thread>
using namespace std;
atomic<int> a(0);
void sum() {
for(int i=0; i!=10000000; i++) {
a++;
}
}
int main() {
// cout << a.is_lock_free() << endl;
// 启动四个线程
thread t1(sum);
thread t2(sum);
thread t3(sum);
thread t4(sum);
t1.join();
t2.join();
t3.join();
t4.join();
int ret = a.load();
cout << ret << endl;
return 0;
}mutex
#include<iostream>
#include<thread>
#include<mutex>
using namespace std;
mutex m;
int a = 0;
int b = 0;
void sum() {
for(int i=0; i!=10000000; i++) {
m.lock();
a++;
m.unlock();
}
}
int main() {
// 启动四个线程
thread t1(sum);
thread t2(sum);
thread t3(sum);
thread t4(sum);
t1.join();
t2.join();
t3.join();
t4.join();
cout << a << endl;
return 0;
}运行
[email protected] cpptest % time ./atomic
40000000
./atomic 3.41s user 0.01s system 395% cpu 0.865 total
[email protected] cpptest % time ./mutex
40000000
./mutex 2.13s user 4.70s system 317% cpu 2.153 total可见使用atomic后,系统调用的开销显著降低,性能得以提升
双版本切换
该方案的思路是使用双版本保存统计信息。当需要记录统计参数时,先获取当前版本的index,可以获得往哪个版本写。新开一个线程,每隔一个时间间隔切换index,同时打印之前的统计参数
代码
#include<iostream>
#include<atomic>
#include<vector>
#include<thread>
#include<unistd.h>
using namespace std;
struct Info {
int a{0};
void clear() {a=0;}
};
atomic<int> Index(0); // 指向当前的版本
vector<Info*> vec_infos; // 保存双版本的信息
void print_info(int idx) { // 打印idx版本的统计参数
cout << vec_infos.at(idx)->a << endl;
}
void clear_info(int idx) { // 将idx版本的统计参数清零
vec_infos.at(idx)->a = 0;
}
void printInfo() {
int i=0; // 保证函数能退出
int idx=0;
while(i!=10) {
sleep(1);
int next_idx = (idx+1) % 2;
clear_info(next_idx); // 将即将使用的Info清零
Index.store(next_idx); // 切换index,之后的写入的统计数据会放到另一个Info中
print_info(idx); // 打印之前的统计数据
idx = next_idx; // 指向新的index
i++;
}
}
void writeInfo() { // 写入统计参数
while(true) {
int idx = Index.load(); // 获取当前的index
vec_infos.at(idx)->a++;
}
}
int main() {
Info* info1 = new Info();
Info* info2 = new Info();
vec_infos.push_back(info1);
vec_infos.push_back(info2); // 双版本统计参数初始化
thread t1(printInfo); // 启动打印线程
thread t2(writeInfo); // 启动模拟写入统计参数的线程
t1.join();
return 0;
}这份代码其实并不严密,写入统计参数时,可能已经完成打印了,导致数据丢失。首先这种概率并不大,atomic的store操作的时间开销是大于普通变量赋值的;其次是对于统计信息,即使丢少量数据,问题不大;再则我们可以将intervel的时间分成两份,在store操作和print_info之前等待一段时间,确保之前版本的数据都被写入。
边栏推荐
- Analysis report on the development trend and prospect scale of silicon intermediary industry in the world and China Ⓩ 2022 ~ 2027
- 20个实用的 TypeScript 单行代码汇总
- Dragon lizard community open source coolbpf, BPF program development efficiency increased 100 times
- 单工,半双工,全双工区别以及TDD和FDD区别
- Yarn restart applications record recovery
- Analysis report on production and marketing demand and investment forecast of global and Chinese diamond powder industry Ⓤ 2022 ~ 2027
- Enter the top six! Boyun's sales ranking in China's cloud management software market continues to rise
- 【剑指Offer】54. 二叉搜索树的第k大节点
- C语言订餐管理系统
- Google Earth engine (GEE) - Global Human Settlements grid data 1975-1990-2000-2014 (p2016)
猜你喜欢

分布式事务简介(seata)

Summary of interview questions (1) HTTPS man in the middle attack, the principle of concurrenthashmap, serialVersionUID constant, redis single thread,

Google Earth engine (GEE) - Global Human Settlements grid data 1975-1990-2000-2014 (p2016)

Application of 5g industrial gateway in scientific and technological overload control; off-site joint law enforcement for over limit, overweight and overspeed

孔松(信通院)-数字化时代云安全能力建设及趋势

Enter the top six! Boyun's sales ranking in China's cloud management software market continues to rise

Explain IO multiplexing, select, poll, epoll in detail
![[anwangbei 2021] Rev WP](/img/98/ea5c241e2b8f3ae4c76e1c75c9e0d1.png)
[anwangbei 2021] Rev WP

Six years of technology iteration, challenges and exploration of Alibaba's globalization and compliance

玩转MongoDB—搭建MongoDB集群
随机推荐
洞态在某互联⽹⾦融科技企业的最佳落地实践
进入前六!博云在中国云管理软件市场销量排行持续上升
[machine learning] VAE variational self encoder learning notes
Kongsong (Xintong Institute) - cloud security capacity building and trend in the digital era
“国防七子”经费暴增,清华足足362亿元,甩第二名101亿 |全国高校2022预算大公开...
单工,半双工,全双工区别以及TDD和FDD区别
App自动化测试开元平台Appium-runner
Fiori applications are shared through the enhancement of adaptation project
QT社团管理系统
8款最佳实践,保护你的 IaC 安全!
我们该如何保护自己的密码?
A new book by teacher Zhang Yujin of Tsinghua University: 2D vision system and image technology (five copies will be sent at the end of the article)
Global and Chinese styrene acrylic lotion polymer development trend and prospect scale prediction report Ⓒ 2022 ~ 2028
[Jianzhi offer] 54 The k-th node of binary search tree
【剑指 Offer】55 - II. 平衡二叉树
焱融看 | 混合云时代下,如何制定多云策略
2022上半年英特尔有哪些“硬核创新”?看这张图就知道了!
关于佛萨奇2.0“Meta Force原力元宇宙系统开发逻辑方案(详情)
2.15 summary
6年技术迭代,阿里全球化出海&合规的挑战和探索