一次奇怪的现象...

在上周的测试过程中,发现随着程序运行时间的增长[速度不快],每个port的数据包miss高达千万级别的,也就是能处理就几十万的数据包,由处理千万到几十万,这个现象特别奇怪;然后多次运行一段时间也是如此,就记着这个问题待解决,然后又通过不同的源[速度非常快]一会造成了上述现象,猜测是不是由同一个原因引起的。

虽然业务代码比较复杂,从收队列中取数据包,处理,再决定是转发还是丢弃,input到发队列中和丢弃也是有可能的。测试了纯转发和丢弃数据包并不费时,剩下的就是处理了。仔细分析处理部分代码,在可疑的地方加上了cpu转数,然后分析后发现求hash计算只消耗几百到几千的转数,然后进行hash查找的时候也就几百几千,但在有些情况下达到一两万左右,可能是因为在key-data插入过程中有冲突,所以在查找时比较次数有点多和key的长度有关。然后在申请资源前直接返回了,发现这个问题不存在了,于是猜测是申请资源的时候造成竞争导致的。通过perf工具也能发现问题所在,但是为啥对于变化比较慢的不同源一开始没有出现那种情况,而且是越往后才出现的。

后来分析相关申请资源代码后:

 68 void *
 69 rte_malloc_socket(const char *type, size_t size, unsigned align, int socket_arg)
 70 {
 71     struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
 72     int socket, i;
 73     void *ret;
 74 
 75     /* return NULL if size is 0 or alignment is not power-of-2 */
 76     if (size == 0 || (align && !rte_is_power_of_2(align)))
 77         return NULL;
 78 
 79     if (!rte_eal_has_hugepages())
 80         socket_arg = SOCKET_ID_ANY;
 81 
 82     if (socket_arg == SOCKET_ID_ANY)
 83         socket = malloc_get_numa_socket();
 84     else
 85         socket = socket_arg;
 86 
 87     /* Check socket parameter */
 88     if (socket >= RTE_MAX_NUMA_NODES)
 89         return NULL;
 90 
 91     ret = malloc_heap_alloc(&mcfg->malloc_heaps[socket], type,
 92                 size, 0, align == 0 ? 1 : align, 0);
 93     if (ret != NULL || socket_arg != SOCKET_ID_ANY)
 94         return ret;
 95 
 96     /* try other heaps */
 97     for (i = 0; i < RTE_MAX_NUMA_NODES; i++) {
 98         /* we already tried this one */
 99         if (i == socket)
100             continue;
101 
102         ret = malloc_heap_alloc(&mcfg->malloc_heaps[i], type,
103                     size, 0, align == 0 ? 1 : align, 0);
104         if (ret != NULL)
105             return ret;
106     }
107 
108     return NULL;
109 }

148 /*  
149  * Main function to allocate a block of memory from the heap.
150  * It locks the free list, scans it, and adds a new memseg if the
151  * scan fails. Once the new memseg is added, it re-scans and should return
152  * the new element after releasing the lock.
153  */             
154 void * 
155 malloc_heap_alloc(struct malloc_heap *heap,
156         const char *type __attribute__((unused)), size_t size, unsigned flags,
157         size_t align, size_t bound)
158 {   
159     struct malloc_elem *elem;
160         
161     size = RTE_CACHE_LINE_ROUNDUP(size);
162     align = RTE_CACHE_LINE_ROUNDUP(align);
163         
164     rte_spinlock_lock(&heap->lock);
165         
166     elem = find_suitable_element(heap, size, flags, align, bound);
167     if (elem != NULL) {
168         elem = malloc_elem_alloc(elem, size, align, bound);
169         /* increase heap's count of allocated elements */
170         heap->alloc_count++;
171     }
172     rte_spinlock_unlock(&heap->lock);
173 
174     return elem == NULL ? NULL : (void *)(&elem[1]);
175 }

如上,因为内存资源是加了自旋锁rte_spinlock_lock,故多个线程在申请的时候进行互斥,当时知道这里是这么实现的,一开始跑的时候并不会出现那种情况,是在运行一段时间后出现的,这就有问题了。那为什么在以非常快的速度变化源的时候一下子就出现问题了呢?这个问题也好分析。

后来写了个资源管理,本身资源管理不会包括调用rte_malloc_socket和rte_free,里面使用到的一定的技巧。包括申请与释放,完全不会造成资源泄露和把竞争的概率降的基几没有,也在一些点面作了平衡[比如申请多少,什么时候释放]。后来用了多种不同的极端测试,以上问题都解决了,回归了正常。

由于在一秒内每个线程可能需要处理三四百万个数据包,为每个数据包分配一个资源,加上一定的超时时间,累计的可能达到八九千万,那对于超时处理,在这方面也作了优化,避免了不会超时的资源在其他tick处理。因为如果每次都去操作超时资源,那么工作线程就不用做其他事了,那样miss就又回到原来的情况了。

纵观整个逻辑,在工作线程处理过程中,基本没有线程间资源的竞争,尽量减少不必要的计算,把资源局部化,对上一次的结果[比较耗时的]作了缓存或索引,那么下一次在进行计算时直接把可能要进行下一步计算的结果给直接取出来了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,100评论 18 139
  • layout: posttitle: 《Java并发编程的艺术》笔记categories: Javaexcerpt...
    xiaogmail阅读 5,728评论 1 19
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 20171010周慧心赏第57天 今天是双十节,十全十美的好日子,希望大家都能美满幸福哈哈 亲爱的老公...
    hmzhou阅读 198评论 0 5
  • 那时候他初三,我初二。十字开头的年纪谈什么爱情。 我们认识五年,我喜欢他四年,他像一个大哥哥一样,总是那么阳光...
    我有孤独和烈酒阅读 274评论 0 1