摘要:为了能加快相关任务的高效执行,TaurusDB采用多线程技术处理的方式,增加处理器单元的吞吐能力,从而提高存储端的执行效率。

1. TaurusDB背景

随着云计算进入2.0时代,数据急剧膨胀,这对实现数据库的高可靠、高性能、高吞吐的目标产生了巨大的挑战。如图1 所示,TaurusDB是华为自研的最新一代企业级具备横向扩展、海量存储能力的分布式数据库,其采用了计算存储分离,一写多读的分布式架构。将原本计算层的高密度存储相关压力下沉到存储层,极大地释放了计算层的算力。但同时将原来的存储IO转移到了网络IO,这也就是意味着,存储层将面临来自计算层风暴级的压力。如果存储层不能快速响应计算层的读写请求,会极大影响用户的使用体验。

图1 TaurusDB整体架构图2 slice功能组件

从图2可知,TaurusDB的存储层,不单单只做存储相关的工作,也需要大量的算力,比如consolidation生成特定数据页、compation回收旧版本数据、BufferPool缓存热点数据页等任务。为了能加快这些任务的高效执行,我们首先能想到的就是能够并行执行这些任务,也就是采用多线程技术处理的方式,增加处理器单元的吞吐能力,从而提高存储端的执行效率。

2.线程池化设计思想

2.1线程为什么需要池化

首先,线程是稀缺的资源,如果频繁创建和销毁线程的开销是可观的,所占用的时间可能多于实际任务的执行;且当需要执行任务时,都去创建一个对应的线程去处理,那么服务器的资源(比如地址空间和内核参数)很快就会被耗尽,导致而导致OOM问题。

其次,通过事先创建好一定数量的线程并置于公共池之中,这样当有任务需要执行时,只需从公共池取一个线程执行当前的任务即可,待任务结束后,此线程又可以执行其他任务或处于休眠状态,等待下一次被调度,达到线程资源重复使用的目的。

2.2线程池如何管理

为了能有效的管理多线程,TaurusDB存储端采用了如图3的线程池模型。

图3 线程池模型

ThreadPool: 主要负责控制线程池的大小、状态变更、线程的创建、销毁、调度策略的选取;

Scheduler:负责具体任务的接收、被调度的顺序,并触发任务的执行;

Worker:负责具体任务的执行;

Monitor:负责监控线程执行任务时是否出现异常,以及异常告警,比如线程执行一次任务长时间执行未能结束。

2.3 线程池的调度策略

当前TaurusDB存储端线程池支持三种策略:先进先出调度(FifoScheduler)、定时调度(TimeScheduler)、基于容量调度(CapacityScheduler)。

对于FifoScheduler和TimeScheduler,比较容易理解。当有任务需要执行时,只需将此任务存放在一个队列即可,有scheduler按照顺序逐一调度即可。

对于CapacityScheduler,是一种基于事先为某一类型的任务预留可执行线程的思想,其预留的线程个数由下发任务的用户指定。具体调度过程见图4。

图4 CapacityScheduler调度

比如:

初始化线程大小为10,TaskType1预留线程数4,TaskType2:预留线程数5,TaskTypeN:预留线程数4

当线程池处于如图4状态时,任务类型是1和3的尚未达到预留值,任务类型N已达到阈值。此时如果Threadpool中处于idle的线程数为1,则该线程将会被调度到任务类型为2的队列中。

2.4 任务异常监控告警

我们知道,一旦任务被调度的线程执行过程中,可能会出现异常情况,比如线程死锁,导致该任务不能按照预期推进,轻者引发系统出现CPU、IO等系统资源使用率飚高的情况,严重者会导致系统down情形。比如TaurusDB的存储端,执行log的checkpoint的线程出现长时间卡顿,会导致存储端旧的log不能正常回收,导致磁盘空间逐步膨胀,进而影响存储端其他各个模块平滑的推进。如果能够识别出处于异常状态的线程,并能够进行告警,基于事先自定义规则进行修复,将能够持续保证存储端业务的连续性。

线程池Monitor组件就是用于识别处于异常状态的线程,其基本思想就是,定期巡检线程池中的各线程处于状态,如果发现线程状态长时间未更新,则判定该线程处于异常状态,上报告警,并基于相应的处理规则处理。

3. 下一步演进方向

从2.3中可以看出,CapacityScheduler策略是基于实际在执行的线程数,作为idle线程线程被调度的依据,尚未衡量实时任务的重要程度。考虑这样一种场景,如果有两种类型的任务A、B,在某一时间,用于执行A、B任务的线程数恰好线程或差值极小,但B类型任务的优先级大于A任务,这时可能出现idle线程被调度执行A类型任务,B类型任务不能分配到充足的线程数(预留值是静态分配),用于加快推进任务的处理。

考虑的方案:

1.限制类型任务类型队列的长度,这样可以均衡各类型任务的调度,不至于某一类或几类任务数过多;

2.在系统资源有限的前提下,支持动态伸缩线程池大小的功能,这样可以在工作负载过重时,扩充线程池大小,用于调度到急需执行的任务;

3.099进一步细化CapacityScheduler策略,采用任务的重要程度和实际执行的线程数的规则,作为idle线程被调度的依据。

点击关注,第一时间了解华为云新鲜技术~

解密TaurusDB存储端高并发之线程池的更多相关文章

  1. java高并发之线程池

    Java高并发之线程池详解   线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对 ...

  2. Java高并发之线程池详解

    线程池优势 在业务场景中, 如果一个对象创建销毁开销比较大, 那么此时建议池化对象进行管理. 例如线程, jdbc连接等等, 在高并发场景中, 如果可以复用之前销毁的对象, 那么系统效率将大大提升. ...

  3. 1.6 JAVA高并发之线程池

    一.JAVA高级并发 1.5JDK之后引入高级并发特性,大多数的特性在java.util.concurrent 包中,是专门用于多线程发编程的,充分利用了现代多处理器和多核心系统的功能以编写大规模并发 ...

  4. Linux + C + Epoll实现高并发服务器(线程池 + 数据库连接池)(转)

    转自:http://blog.csdn.net/wuyuxing24/article/details/48758927 一, 背景 先说下我要实现的功能,server端一直在linux平台下面跑,当客 ...

  5. Java并发之线程池ThreadPoolExecutor源码分析学习

    线程池学习 以下所有内容以及源码分析都是基于JDK1.8的,请知悉. 我写博客就真的比较没有顺序了,这可能跟我的学习方式有关,我自己也觉得这样挺不好的,但是没办法说服自己去改变,所以也只能这样想到什么 ...

  6. Java并发之——线程池

    一. 线程池介绍 1.1 简介 线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池的基本思想还是一种对象池的思想,开辟一块内存空间,里面存放了众多(未死亡 ...

  7. java并发之线程池的使用

    背景 当系统并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要消耗大量的系统资源. 所以需要一个办法使得线程可以 ...

  8. Java高并发之线程基本操作

    结合上一篇同步异步,这篇理解线程操作. 1.新建线程.不止thread和runnable,Callable和Future了解一下 package com.thread; import java.tex ...

  9. 高并发之——不得不说的线程池与ThreadPoolExecutor类浅析

    一.抛砖引玉 既然Java中支持以多线程的方式来执行相应的任务,但为什么在JDK1.5中又提供了线程池技术呢?这个问题大家自行脑补,多动脑,肯定没坏处,哈哈哈... 说起Java中的线程池技术,在很多 ...

随机推荐

  1. (Java实现) 洛谷 P1042 乒乓球

    题目背景 国际乒联现在主席沙拉拉自从上任以来就立志于推行一系列改革,以推动乒乓球运动在全球的普及.其中1111分制改革引起了很大的争议,有一部分球员因为无法适应新规则只能选择退役.华华就是其中一位,他 ...

  2. Java实现 蓝桥杯VIP 基础练习 报时助手

    题目描述 给定当前的时间,请用英文的读法将它读出来. 时间用时h和分m表示,在英文的读法中,读一个时间的方法是: 如果m为0,则将时读出来,然后加上"o'clock",如3:00读 ...

  3. Java实现 蓝桥杯VIP 算法训练 字符串逆序

    问题描述 给定一个字符串,将这个串的所有字母逆序后输出. 输入格式 输入包含一个字符串,长度不超过100,字符串中不含空格. 输出格式 输出包含一个字符串,为上面字符串的逆序. 样例输入 tsinse ...

  4. Java实现 LeetCode 306 累加数

    306. 累加数 累加数是一个字符串,组成它的数字可以形成累加序列. 一个有效的累加序列必须至少包含 3 个数.除了最开始的两个数以外,字符串中的其他数都等于它之前两个数相加的和. 给定一个只包含数字 ...

  5. Java实现LeetCode_0028_ImplementStrStr

    package javaLeetCode.primary; import java.util.Scanner; public class ImplementStrStr_28 { public sta ...

  6. Java实现 洛谷 P2141 珠心算测验

    import java.util.LinkedList; import java.util.Scanner; public class Main { private static Scanner ci ...

  7. java实现转方阵

    /* 对一个方阵转置,就是把原来的行号变列号,原来的列号变行号 例如,如下的方阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 转置后变为: 1 5 9 13 2 6 ...

  8. vue的第一个commit分析

    为什么写这篇vue的分析文章? 对于天资愚钝的前端(我)来说,阅读源码是件不容易的事情,毕竟有时候看源码分析的文章都看不懂.每次看到大佬们用了1-2年的vue就能掌握原理,甚至精通源码,再看看自己用了 ...

  9. iOS-字典转模型(单模型)的实现

    用模型取代字典的好处 使用字典的坏处 一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编译器不会有任何友善提示,需要手敲, eg:dict[@"name&quo ...

  10. .NET开发者省份分布排名

    什么叫.NET开发者省份分布排名呢? 顾名思义,这几个词大家都认识,.NET开发者都集中在城市,涵盖一线城市到五线城市.排名的方法非常简单粗暴,就是根据本公众号(dotnet跨平台)的省份订阅读者数量 ...