文档章节

分布式、高并发、多线程Multithreading

涅槃Ls
 涅槃Ls
发布于 2017/04/09 12:25
字数 4222
阅读 1441
收藏 4
点赞 0
评论 0

一、分布式系统

在计算机领域,当单机性能达到瓶颈时,一般有两种方式解决性能问题,

  • 一是堆硬件,进一步提升配置;
  • 二是分布式,水平扩展、垂直拆分。

分布式系统有很多种:分布式文件系统、分布式数据库、分布式WebService、分布式计算等等,

面向的情景不同,但分布式的思路大致相同,万法归一吧!

以下内容主要来自:分布式系统架构思想

 

1.1、分布式系统实现的两种方式【水平扩展、垂直拆分】

1.1.1、简单的例子

假设我们有一台服务器,它可以承担1百万/秒的请求,这个请求可以的是:通过http访问网页、通过tcp下载文件、jdbc执行sql、RPC调用接口等等方式,现在我们有一条数据的请求是2百万/秒,很显然服务器很难hold住,会各种拒绝访问,甚至宕机,怎么办呢?

一台机器解决不了的问题,那就两台。所以我们加一台机器,每台承担1百万。如果请求继续增加呢,两台解决不了的问题,那就三台呗。这种方式我们称之为水平扩展,如果实现请求的平均分配便是负载均衡了。

另一个例子,我们现在有两个数据请求,数据190万,数据280万,上面那台机器也hold不住,我们加一台机器来负载均衡一下,每台机器处理45万数据1和40万数据2,但是平分太麻烦,不如一台处理数据1,一台处理数据2,同样能解决问题,这种方式我们称之为垂直拆分。

水平扩展和垂直拆分是分布式架构的两种思路,但并不是一个二选一的问题,更多的是兼并合用。下面介绍一个实际的场景。这也是许多互联网的公司架构思路。

1.1.2、实际的例子

某些公司的计算机系统很是庞大,自然是一个整的分布式系统,为了方便组织管理,公司将整个技术部按业务和平台拆分为部门:订单的、会员的、商家的等等,而每个部门有自己的web服务器集群、数据库服务器集群,

通过同一个网站访问的链接可能来自于不同的服务器和数据库,对网站及底层对数据库的访问被分配到了不同的服务器集群,这个便是典型的按业务做的垂直拆分,每个部门的服务器在hold不住时,会有弹性的扩展,这便是水平扩展。

在数据库层,有些表非常大,数据量在亿级,如果只是纯粹的水平的扩展并不一定最好,

如果对表进行拆分,比如可以按用户id进行水平拆表,通过对id取模的方式,将用户划分到多张表中,同时这些表也可以处在不同的服务器。

按业务的垂直拆库 和 按用户水平拆表 是分布式数据库中通用的解决方案。

1.2、负载均衡

前面我们谈到了分布式来解决性能问题,但其附带的问题是怎么分布,即如何负载均衡。这里要解决的问题是当客户端请求时,应该让它请求分布式系统中哪一台服务器,通常的做法是通过一台中间服务器来给客服端分配目标服务器。

这里同样拿两个不同的分布式系统做说明,

下图左边 是分布式文件系统FastDFS,

下图右边 是一个用于分布式的RPC中间件。

  • FastDFS的一次文件下载请求过程是这样的

    1. client询问tracker可以下载指定文件的storage;

    2. tracker返回一台可用的storage;

    3. client直接和storage通信完成文件下载。

其中tracker便是负载均衡服务器,storage是存储文件和处理上传下载请求的服务器。

 

  • 而另一个RPC中间件Hedwig也是类似的

    1. client询问zookeeper哪台server可以执行请求;

    2. zookeeper返回一台可用server;

    3. client直接与service完成一次RPC。

zookeeper是分布式系统中一个负载均衡框架,google的chubby的一个开源实现,是Hadoop和Hbase的重要组件。

同样的在http中,常听说的nginx也是一个负载均衡服务器,它面向的是分布式web服务器。

1.3、同步问题

分布式系统中,解决了负载均衡的问题后,另外一个问题就是数据的一致性了,这个就需要通过同步来保障。根据不同的场景和需求,同步的方式也是有选择的。

在分布式文件系统中,比如商品页面的图片,如果进行了修改,同步要求并不高,就算有数秒甚至数分钟的延迟都是可以接受的,因为一般不会产生损失性的影响,因此可以简单的通过文件修改的时间戳,隔一定时间扫描同步一次,可以牺牲一致性来提高效率。

但银行中的分布式数据库就不一样了,一丁点不同步就是无法接受的,甚至可以通过加锁等牺牲性能的方式来保障完全的一致。

在一致性算法中paxos算法是公认的最好的算法,chubby、zookeeper中paxos是它保证一致性的核心。

 

二、高并发

高并发,简言之:短时间,大量请求。

以下内容主要来源于:java系统高并发解决方案(转载)

----------------------------------------------------------------------------

2.1、并发与分布

并发反映的是同时有多少量,比如互联网上的在线直播,可能有几万人需要同时访问服务器,这就是并发。

分布是将任务分发到不同的点上去,一般分布式最多的就是分布式计算。通过某种分布式编程方式,在不同的系统上利用各自的CPU,内存等进行计算,将结果汇集至控制中心,进行处理。

  • 高并发也可以通过分布式方式解决,比如云的概念,云存储就需要通过分布式的系统,可以实现高并发的存储。这需要取决于需求和容忍度。
  • 对于互联网这个具体领域,高并发的解决不一定需要通过分布式系统,可以通过DNS轮询,实现服务器负载的分担。所有的服务器都是一样的配置,访问同样的内容。
  • 对于一些数据库处理系统,需要快速返回结果,也可以通过分布式系统,将计算任务分摊到不同的系统上去,加快计算的速度。

2.2、解决高并发的常见经验

大型网站,比如门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:

  • 使用高性能的服务器
  • 高性能的数据库
  • 高效率的编程语言
  • 还有高性能的Web容器

以上的几个方面在一定程度上意味着更大的投入,会经常遇到瓶颈,没有很好的扩展性,所以还没法根本解决大型网站面临的高负载和高并发问题。

下面我从低成本、高性能和高扩张性的角度的一些经验:

  • HTML静态化
  • 图片服务器分离
  • 数据库集群和库表散列
  • 缓存
  • 镜像
  • 负载均衡
  • ......

2.2.1、高并发高负载类网站关注点之数据库

    首先是数据库,这是大多数应用所面临的首个SPOF【single point of failure 单一故障点】。
常用的优化措施是M-S(主-从)方式进行同步复制,将查询和操作和分别在不同的服务器上进行操作。

    推荐的是M-M-Slaves方式,2个主Mysql,多个Slaves,需要注意的是,虽然有2个Master,但是同时只有1个是Active,我们可以在一定时候切换。之所以用2个M,是保证M不会又成为系统的SPOF。
Slaves可以进一步负载均衡,可以结合LVS,从而将select操作适当的平衡到不同的slaves上。
    以上架构可以抗衡到一定量的负载,但是随着用户进一步增加,你的用户表数据超过1千万,这时那个M变成了SPOF。你不能任意扩充Slaves,否则复制同步的开销将直线上升,怎么办?我的方法是表分区,从业务层面上进行分区。最简单的,以用户数据为例。根据一定的切分方式,比如id,切分到不同的数据库集群去。

    全局数据库用于meta数据的查询。缺点是每次查询,会增加一次,比如你要查一个用户nightsailer,你首先要到全局数据库群找到nightsailer对应的cluster id,然后再到指定的cluster找到nightsailer的实际数据。每个cluster可以用m-m方式,或者m-m-slaves方式。这是一个可以扩展的结构,随着负载的增加,你可以简单的增加新的cluster进去。

2.2.2、高并发高负载网站的系统架构之HTML静态化

    其实大家都知道,效率最高、消耗最小的就是纯静态页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量内容并且频繁更新的网站,我们无法全部手动去挨个实现,于是出现了我们常见的信息发布系统CMS,像我们常访问的各个门户站点 的新闻频道,甚至他们的其他频道,都是通过信息发布系统来管理和实现的,信息发布系统可以实现最简单的信息录入自动生成静态页面,还能具备频道管理、权限 管理、自动抓取等功能,对于一个大型网站来说,拥有一套高效、可管理的CMS是必不可少的。
   同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询但是内容更新很小的应用,可以考虑使用html静态化来实现,比如论坛 中论坛的公用设置信息,这些信息目前的主流论坛都可以进行后台管理并且存储再数据库中,这些信息其实大量被前台程序调用,但是更新频率很小,可以考虑将这 部分内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求高并发。

网站HTML静态化解决方案 
当一个Servlet资源请求到达WEB服务器之后我们会填充指定的JSP页面来响应请求:

    HTTP请求---Web服务器---Servlet--业务逻辑处理--访问数据--填充JSP--响应请求

HTML静态化之后:

    HTTP请求---Web服务器---Servlet--HTML--响应请求

2.2.3、高并发高负载类网站关注点之缓存、负载均衡、存储

2.2.4、高并发高负载网站的系统架构之图片服务器分离 
    大家知道,对于Web 服务器来说,不管是Apache、IIS还是其他容器,图片是最消耗资源的,于是我们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至很多台图片服务器。这样的架构可以降低提供页面访问请求的服务器系统压力,并且可以保证系统不会因为图片问题而崩溃。

2.2.5、高并发高负载网站的系统架构之数据库集群和库表散列

    大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快无法满足应用,于是我们需要使用数据库集群或者库表散列。
  
  在数据库集群方面,很多数据库都有自己的解决方案,Oracle、Sybase等都有很好的方案,常用的MySQL提供的Master/Slave也是类似的方案,您使用了什么样的DB,就参考相应的解决方案来实施即可。
  
   上面提到的数据库集群由于在架构、成本、扩张性方面都会受到所采用DB类型的限制,于是我们需要从应用程序的角度来考虑改善系统架构,库表散列是常用并且最有效的解决方案。我们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不同的模块对应不同的数据库或者表,再按照一定的策略对某个页面或者 功能进行更小的数据库散列,比如用户表,按照用户ID进行表散列,这样就能够低成本的提升系统的性能并且有很好的扩展性。

------------------------------------------------------------------------------

三、多线程 Multithreading

3.1、Thread 基本概念与特点

多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。

具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。

  • 多线程:指的是这个程序(一个进程)运行时产生了不止一个线程
  • 并行与并发:
    • 并行:多个cpu实例或者多台机器同时执行一段处理逻辑,是真正的同时。
    • 并发:通过cpu调度算法,让用户看上去同时执行,实际上从cpu操作层面不是真正的同时。并发往往在场景中有公用的资源,那么针对这个公用的资源往往产生瓶颈,我们会用TPS或者QPS来反应这个系统的处理能力。

3.2、Thread 生命周期

关于Java中线程的生命周期,首先看一下下面这张较为经典的图:

上图中基本上囊括了Java中多线程各重要知识点。掌握了上图中的各知识点,Java中的多线程也就基本上掌握了。

3.3、Thread五种基本状态

  • 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
  • 就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
  • 运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就     绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
  • 阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
    • 1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
    • 2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
    • 3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
  • 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。

© 著作权归作者所有

共有 人打赏支持
涅槃Ls

涅槃Ls

粉丝 6
博文 12
码字总数 41086
作品 0
深圳
QA/测试工程师
python通过snmp协议运用多线程获取多台主机网卡信息,写入数据库

#-- coding:utf-8 --import netsnmpclass SnmpClass(object): def getflow(): getflow() community:为团体字 运用多线程获取多台主机网卡信息,写入数据库。 多线程(英语:multithreading)...

渣渣辉
07/12
0
0
Java并发库(Java Concurrency)

原文地址 译文地址 译者:张坤等 Java并发性和多线程介绍(Java Concurrency / Multithreading Tutorial) 多线程的优点(Multithreading Benefits) 多线程的代价(Multithreading Costs) ...

暗之幻影
2016/12/17
19
0
并发编程-锁的发展和主流分布式锁比较总结

一、锁的发展 系统结构由传统的“单应用服务--》SOA --》微服务 --》无服务器” 的演进过程中,场景越来越复杂,由单体应用的但进程中多线程并发的内存锁,随着互联网场景越来越复杂,在复杂...

贾浩v
2017/10/24
0
0
为什么servlets是非线程安全的?

Servlet instances are inherently not thread safe because of the multi threaded nature of the Java programming language in general. The Java Virtual Machine supports executing th......

666B
2016/11/03
27
0
A Year Of Books - 2016 Javaer书单

A Year Of Books – 2016 Javaer书单 (PS:欢迎留言推荐,很多来自白衣大哥的推荐) 1. OS & Networking 《编码 : 隐匿在计算机软硬件背后的语言》 《Linux内核设计与实现 第3版》 《WireShark...

泥沙砖瓦浆木匠
2016/04/25
128
2
阿里,百度,腾讯等一线互联网公司中,Java开发的招聘标准

金三银四的跳槽热潮即将过去,在这两个月的跳槽的旺季中,作为互联网行业的三大巨头,百度、阿里巴巴、腾讯对于互联网人才有很大的吸引力,他们的员工也是众多互联网同行觊觎的资深工程师、管...

javaxuexi123
04/20
0
0
Fourinone如何实现并行计算和数据库引擎

关于并行计算的概念有非常多,硬件落地其实就只有两种,CPU上的并行计算和GPU上的并行计算,GPU做点积这样的矢量计算(矩阵计算)有优势,但目前还运行不了操作系统和数据库,比较多用于研究...

fourinone
2016/03/03
313
0
面试分享 -- 分享近期参加面试一些感概

大家好,由于本人最近参加一些公司的面试(神马情况,年底跳槽),哈哈 这是题外话了,一个月内每周都有面试,纵观真个行业线,面试的侧重点有悄然发生了变化,此时此刻才指导自己有很多的技...

边缘行者
2012/11/30
0
15
支付宝架构师眼里的高并发架构

前言 高并发经常会发生在有大活跃用户量,用户高聚集的业务场景中,如:秒杀活动,定时领取红包等。 为了让业务可以流畅的运行并且给用户一个好的交互体验,我们需要根据业务场景预估达到的并...

java高级分享
01/05
0
0
2018年的学习计划

转眼间,2017年过去了,在过去的一年里,成长颇多,感受颇多,当然,收获也颇多。能够在2017年里,将quartz,xxl-job,elastic-job-Lite源码读一遍,学到了很多东西。 整理了一下自己感兴趣的...

一滴水的坚持
01/06
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Git 2.18版本发布:支持Git协议v2,提升性能

Git 2.18版本发布:支持Git协议v2,提升性能Git 2.18版本发布:支持Git协议v2,提升性能 新版本协议的主要驱动力是使 Git 服务端能够对各种 ref(分支与 tag)进行过滤操作。 这就意味着,G...

linux-tao
30分钟前
0
0
python浏览器自动化测试库【2018/7/22-更新】

64位py2.7版本 更新 document_GetResources 枚举页面资源 document_GetresourceText 获取指定url的内容 包括页面图片 下载地址下载地址 密码:upr47x...

开飞色
46分钟前
28
0
关于DCL双重锁失效及解决方案

关于DCL双重锁失效及解决方案 Double Check Lock (DCL)实现单例 DCL 方式实现单例的优点是既能够在需要时才初始化单例,又能够保证线程安全,且单例对象初始化后调用getInstance方法不进行...

DannyCoder
52分钟前
0
0
PowerDesigner 16.5 安装配置

PowerDesigner16.5破解版是一款业内领先且开发人员常用的数据库建模工具,PowerDesigner可以从物理和概念两个层面设计数据库,方便用户制作处清晰直观的数据流程图和结构模型,欢迎有需要的朋...

Gibbons
今天
0
0
mac Homebrew 指令积累

1通用命令 brew install [包名] //安装包 brew list //列举安装的包 brew info [包名] // 显示安装包的详细信息 mysql 相关 #启动mysql 服务 brew service start mysql my...

Kenny100120
今天
0
0
前端Tips: 创建, 发布自己的 Vue UI 组件库

创建, 发布自己的 Vue UI 组件库 前言 在使用 Vue 进行日常开发时, 我们经常会用到一些开源的 UI 库, 如: Element-UI, Vuetify 等. 只需一行命令, 即可方便的将这些库引入我们当前的项目: n...

ssthouse_hust
今天
1
0
大数据教程(2.13):keepalived+nginx(多主多活)高可用集群搭建教程【自动化脚本】

上一章节博主为大家介绍了目前大型互联网项目的keepalived+nginx(主备)高可用系统架构体系,相信大家应该看了博主的文章对keepalived/nginx技术已经有一定的了解,在本节博主将为大家分享k...

em_aaron
今天
5
0
Git 2.18版本发布:支持Git协议v2,提升性能

在最新的官方 Git 客户端正式版2.18中添加了对 Git wire 协议 v2 的支持,并引入了一些性能与 UI 改进的新特性。在 Git 的核心团队成员 Brandon Williams 公开宣布这一消息前几周,Git 协议 ...

六库科技
今天
0
0
Java8新特性之接口

在JDK8以前,我们定义接口类中,方法都是抽象的,并且不能存在静态方法。所有的方法命名规则基本上都是 public [返回类型] [方法名](参数params) throws [异常类型] {}。 JDK8为接口的定义带...

developlee的潇洒人生
今天
0
0
aop + annotation 实现统一日志记录

aop + annotation 实现统一日志记录 在开发中,我们可能需要记录异常日志。由于异常比较分散,每个 service 方法都可能发生异常,如果我们都去做处理,会出现很多重复编码,也不好维护。这种...

长安一梦
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部