1
pynix 2018-04-29 11:05:29 +08:00
zmq?
|
2
lsmgeb89 2018-04-29 11:14:23 +08:00
boost 里好像有个 lock-free 的,但没研究过。
|
3
duanhui8 OP @pynix 已经集成了 nanomsg,但是发布消息时间太长,导致用户线程 wait,所以考虑再接一个队列,用户线程只向队列写消息,有其他线程负责取数据发送。
|
5
hncqp 2018-04-29 11:23:32 +08:00 via iPhone
同机器的话,手写
|
6
duanhui8 OP @lsmgeb89 嗯嗯,正在测试 lock-free,第一次使用 boost 库,正在研究,所以对性能,原理机制都不太清楚
|
7
orafy 2018-04-29 11:26:13 +08:00
每秒 7000+的写入,还是多线程不需要考虑高性能。
优先考虑易用性,可以考虑 folly 库里的 MPMCQueue |
8
duanhui8 OP @hncqp 大神,小弟技术有限,自己写 是给自己挖坑啊,这程序要求比较高,出错的后果很严重
有什么推荐的吗?有现成的代码也行^_^ |
9
htfy96 2018-04-29 11:27:59 +08:00
如果 N 个消费者等价的话不如开 N 个队列,生产的时候 round-robin 到 N 个队列中的 1 个。用自旋锁+sched_yield 保护队列,感觉对 7k qps 的情况应该还能撑过去
|
11
htfy96 2018-04-29 11:30:41 +08:00
不等价的话楼上的 folly::MPMCQueue 是个比较成熟的方案,不过性能可能没有 round-robin + MPSCQueue 高
|
14
htfy96 2018-04-29 11:50:13 +08:00
@duanhui8 boost::lockfree Boost 1.53 加入的,个人觉得还不太成熟。不过对你这个情景应该够用了
|
16
feverzsj 2018-04-29 11:57:59 +08:00
要数据安全,只能用基于数据库的消息队列,其他消息队列都无法保证数据不丢失
|
17
duanhui8 OP @feverzsj 审计信息,丢个几条也没事。加队列 主要是不能让用户线程 wait 太长,提高响应。队列性能最好高点,然后保障多线程安全,就可以了
|
18
hncqp 2018-04-29 13:19:16 +08:00 via iPhone
|
19
forestyuan 2018-04-29 13:19:20 +08:00
不知道你的程序运行在什么操作系统上,如果是 Windows 的话,Microsoft Message Queue 应该能满足你的要求
|
20
gabon 2018-04-29 13:45:18 +08:00 via Android
ringbuffer 了解一下,可以参考 java 的 disruptor 实现。底层是个环形数组,用硬件 cas 竞争写入,无锁。开发者测试每秒 600w 订单。
|
21
cholerae 2018-04-29 13:57:27 +08:00 2
https://github.com/cameron314/concurrentqueue 线上有服务用了一阵子了,还是挺靠谱的
|
25
shilyx 2018-04-29 14:14:37 +08:00
正在开发,基于 websocket++,发布 /订阅,服务端 C++跨平台,客户端支持 C++、node、js ( web )、python、golang
|
26
nroskill 2018-04-29 18:31:00 +08:00
|
27
hxndg 2018-04-29 19:51:12 +08:00 via Android
dpdk 那个也是 ringbuf,用的原子操作
|
28
fakevam 2018-04-29 21:07:19 +08:00 1
...7000 要啥这么复杂的东西, 起个 unix domain socket, N 个线程打一个线程, 那边 recv 完事
|
29
hardwork 2018-04-30 00:06:29 +08:00 via Android 1
什么场景要跑 200 到 400 线程,这本身就是低性能吧?请教一下各位
|
33
noli 2018-04-30 23:38:07 +08:00
|
34
fakevam 2018-05-01 00:45:22 +08:00
@noli 线程数量无法确定的情况下, 这货的代码不能用...他只能用于线程数固定的场景, 否则会触发死锁, 因为他的 bucket 分配的问题
|
35
fakevam 2018-05-01 00:46:11 +08:00
@noli 另外, 7000 的并发, 要这么复杂的方案做啥, 谁维护? 单线程代码写得稍微好点, libevent 随便路路, 不是随便 10W 的 qps 么...为什么要搞这么复杂的设计...
|
36
noli 2018-05-01 03:58:01 +08:00
@fakevam #34 #35
他不是在 issue 里面提供了 work around 吗? 我觉得这基本不是问题。 一开始我并没有太多关注题主的应用情景。 我甚至不确定他说的 7000 是指整个 queue 的负荷还是单个 producer 的负荷。 如果是 7000 是指整个 Queue 的负荷,那么直接用系统锁就足够了, 但如果是指单个 producer 7000 ops,那确实只能用 这种基于 spinlock 的。 如果题主不太介意局部写入延迟比较大的话,我本人倒是试过不用靠预先分配的解法。 |
37
fakevam 2018-05-01 16:01:08 +08:00
@noli 200 * 7000 是 140W 的 qps, 通过 socket 打网络出去, 你算过带宽么, 单核 socket 小包 15Wqps 很好了, 千兆网卡的话, 100W 就已经是瓶颈了, cpu 再多也不怎么上的去了..万兆网卡的话, 另说...
|
38
noli 2018-05-01 16:15:59 +08:00
@fakevam #37
说不定楼主是土豪金融公司,连光纤延迟都要考虑在内的那种,万兆是标配。 不过按理,如果真的这么大的工作负荷,应该会考虑多个转发点的设计吧? 又或者这种负荷就是要求单个转发点的性能标准? |
42
fakevam 2018-05-01 21:14:39 +08:00
@duanhui8 你没明白我啥意思, 通过 socket 去做队列, 不写队列那么复杂的东西了, 当然, 几万的 tps, 你就是 stl 加锁, 性能也毫无问题, 不要小看现在的 cpu...
直接 libevent, consumer 监听一个本地的 unix domain sock, 所有的 producer 连接 unix domain sock, 然后往里面写, consumer 负责从里面读, 读出来以后, 写到后端 db, 怎么会增加数据库的性能压力... 当然,你就是 stl + lock 也毫无问题, 不要过早优化, 不要过早优化, 不要过早优化, 重要的事说三次, 在你没有压测之前, 把各种乱七八糟的东西都丢掉! 简单的 lock 可以解决 99%的问题, 特别是啥 spinlock 和 lockless lockfree, 把他们当彻底忘记掉, 他们没有意义, 除非你要 ns 级别的延迟. 我特别特别讨厌各种东西, 上来就是复杂设计, 简单的设计, 测过了才知道, 起码拿着 perf 之类的看过了, 热点到底在哪里, 而不是想当然的各种轮子往上套, 套出一堆复杂得没办法维护的东西出来 |
43
superzmy 2018-05-01 21:19:27 +08:00
我这边有一个多线程写单线程读(或者读加锁把数据复制到栈上)的缓冲池,就专门适应这种网络收发。
测试性能 25Mqps ( 2500 万次 /s )实际工作性能 8M qps,或者说 800 万次 /s。数据不定长,跟上面的 concurrencyqueue 定长类型是不一样的。 不过代码不会免费分享 |
44
haibocui 2018-05-01 21:33:09 +08:00 via Android
一个线程一个队列
|