精华内容
下载资源
问答
  • 图片服务系统是各种针对C端系统常见的子系统,它的特点是存储规模大请求频度高,且单张图片的读请求远远高于写请求。后面几篇文章我们将从图片服务系统的需求分析开始,一起来讨论如何进行这类系统的技术选型、概要...

    1、概述

    图片服务系统是各种针对C端系统常见的子系统,它的特点是存储规模大请求频度高,且单张图片的读请求远远高于写请求。后续几篇文章我们将从图片服务系统的需求分析开始,一起来讨论如何进行这类系统的技术选型、概要设计和详细设计,以及在这个过程中需要关注的技术难点。

    虽然由于写作计划的变化,图片服务系统中所涉及的分布式文件系统原理、非关系型数据库原理都还没有讲到,但这些知识点也并不是组成整个图片服务的所有关键点,并且后续的文章中我们会尽快补上对这些知识点的介绍。图片服务系统的讲述会分为四篇文章,前两篇文章我们主要分析图片服务的需求、架构选型和技术方案,后两篇文章进行性能优化和详细设计部分的讲解。由于不能讲解全部的详细设计,所以文章会在最后将整个示例工程的源代码放置在网络上,供有兴趣的读者进行下载。

    2、需求场景

    首先我们给出使用这个图片服务的场景,以便后续内容中根据这个需求场景进行初步架构设计、详细架构设计、技术选型,以及服务中各个功能模块的设计等工作。这是一个中等规模的针对C端的电商服务站点,日平均PV量在百万级别(在国内属于中等规模的站点,例如从Alexa查询到大众点评的日均PV大致为180万、美团日均PV大致为70万、JD日均PV为7500万)。电子商务类型的站点,其特点是一张页面上会出现多张图片,而且基本上不会使用原图而是大量使用缩略图;另外,多个用户经常同时访问同一个页面,所以不但需要使用缓存,而且缓存一般都有多级,否则会产生大量重复的物理I/O请求;最后,这样的电商平台图片服务都属于顶级业务服务,图片规模基本都是以TB计算,小一些规模的也有几个TB,规模更大的可能达到PB级别。

    产品团队针对图片服务的基本功能要求是:需要支持单张或者多张图片上传,这样可以为站点运营人员/商户增强编辑体验,提高工作效率。另外需要在一些特定场景支持水印功能和图片特效功能,但这是优先级较低的功能,而图片的动态缩放则是必备功能,这是因为在站点的各种页面上都基本上不会使用原图而是使用各种等比缩小或中心截取的缩率图片,另外一个原因是一张图片会在各种客户端设备上显示,最常见的是IOS、Android和浏览器,而这些终端设备对图片的像素要求都是不一样的。产品团队针对图片服务的另一个基本要求是支持图片访问统计和报表,这个功能倒不是给终端用户使用的,而是给站点的运营团队准备的。通过访问统计和用户上传图片的报表统计,运营团队可以针对这些基础数据掌握每月的图片热点,而且这些数据可能还会为后期的数据分析所使用。

    接着在与需求团队的沟通过程中,技术团队还推导了一些重要的非功能性需求,例如该图片服务属于整个站点的一个顶层子系统,所以需要保证7 * 24小时不间断运行,换句话说至少需要99.999%的稳定性;另外,图片服务的设计需要满足现有图片数据的割接,最好能够实现原有系统特别是存在在磁盘上的图片的无缝割接;最后,整个系统至少需要30%的冗余存储空间,保证技术团队有足够的时间和空间进行后续的技术改造。。。

    3、技术问题和选型

    那么图片处理系统要关注的主要问题是什么呢?首先是高并发下的图片处理性能问题。图片处理是一项计算密集型操作,例如目前流行的图片缩放算法就有临近值法、双线性插值法、多项卷积法等,图片锐化算法多为拉普拉斯锐化法,图片增强算法可以采用中值滤波法、直方图均衡法或者幂变换法。这些算法都对CPU计算资源和内存资源有较高的要求,特别是高并发请求背景下。而JAVA语言相对于C/C++语言在各种算法执行效率上又有先天的劣势,所以如果不能在性能上进行弥补就需要找到其它在高并发请求背景下加快图片处理效率的办法。其次是图片存储的问题,和存储稳定性安全性的问题。产生这个问题的原因已经在上文中进行了说明,这里就不再进行追溯了。接下来技术团队根据以上这些需求点和技术点,首先圈定了一个图片服务的概要架构设计:

    这里写图片描述

    外层组件表示那些可以和其它服务系统共同使用的组件,以及那些可以从第三方花钱购买的不需要技术团队关注的组件,上图中给出的示例包括:LVS、DNS/智能DNS、CDN等组件。接下来我们对上图中的各个服务层/服务模块进行选型分析。

    3-1、分布式文件系统选型

    分布式文件系统的选型是整个图片服务的重点,因为它提供了所有图片物理文件的存储基础。在分布式文件系统大量应用于生产环境前,解决此类问题一般使用网络块存储方案,例如IBM Storwize V5000 单柜提供24个磁盘位,单柜支持最大72TB存储容量。但这个方案的缺点是单位容量价格较高,另外虽然这各方案也可以较容易扩容,但是扩容费用也是极高的,基于单位建设成本的考虑目前互联网公司都倾向于使用分布式文件系统甚至现成的云存储服务。如果采用分布式文件系统,那可以用的选型就太多了。这里我们先列举几种常用的分布式文件系统方案,然后针对图片文件的特性,再来对这些方案进行排除。这里我们可选择的分布式文件系统包括:HDFS、TFS、MFS、FastdFD和Ceph。

    那么图片服务系统涉及的文件有些什么样的特点呢?首先这些文件相对于视频文件、语音文件而言都不会太大,举个例子来说,虽然目前主流手机相机照相后产生的一张JPEG图片分辨率大致在2500 * 3200像素左右,大小在1MB到3MB之间,甚至更高端的手机照相后产生的JPEG图片文件大小可以达到5MB左右 。但是考虑到网络流量和客户端速度体验等问题,上传到服务器的单张图片大小往往会控制在1MB左右(当然也有特殊的产品需求会要求上传完整的原始图片)。

    另外这些图片的特点是读请求远远高于写请求,对大多数图片而言一旦上传到了服务器就不会发生更改操作了,甚至有的图片系统都不会提供对某张图片的修改功能。可是图片的读请求却会很多而且带有一定周期性,什么意思呢?例如一张商品图片,当这个商品刚刚上架或者处于优惠期时,这张图片的读请求会处于一个高峰,而平时这张图片的读请求次数会处于一个平均水平,当这张图片对应的商品下架后其访问量就会很低了,但图片系统并不能想当然的删除这张图片,这是因为可能后端的运营团队后续进行商品管理和统计时,还会用到这张图片。

    还有一个特点是,虽然图片系统中单张图片的大小不会过大,但是整个图片系统的文件数量规模却会非常庞大了。就像上文说到的:较小的文件规模也会有几个TB,规模更大图片系统甚至可能达到PB级别。最后,图片系统都应该随时留有足够的冗余存储空间,以便应付至少几个月内系统的扩容要求。

    通过以上的分析,大致可以得到图片系统中对于文件存储的部分的要求:高稳定性工作的工作特性,文件系统不能出现系统崩溃的情况——可以出现单节点故障,但是不能整系统崩溃。这个要求决定了文件系统不能只有单个节点,而是多个节点协同工作——分布式文件系统是符合这样选型要求的。另外,文件系统的数据写性能可以不必太优秀,但是数据读性能必须要好,这样才能适应上文描述的读密集型业务。最后,文件系统的扩容应该比较方便,以便减少运维难度。在这个图片服务的示例中,我们将使用Ceph作为文件系统的选型。关于Ceph文件系统的介绍,可以参考其官网的介绍http://www.ceph.com/,在后续的文章中本专题还会专门介绍Ceph文件系统的原理和使用。

    3-2、缓存系统选型

    多级缓存方案在图片服务中是必然的存在,这是由于图片服务的访问特性决定的。一般来说我们会设计三级——四级缓存,它们分别是客户端缓存,网络层缓存,路由层缓存和服务层缓存。如下图所示:

    这里写图片描述

    上图展示了一个四级缓存方案,其中基于Nginx的路由层缓存可有可无(后文会讨论原因),但是另外三级缓存在大多数高压力负载的图片服务中都是必须存在的,无非是采用哪种具体技术组件而已。除了在上文中提到的减少大量重复的物理I/O请求的目的外,在图片服务中使用多级缓存方案还有以下这些原因:

    • 增加客户端访问速度:这是多级缓存方案中的客户端缓存和网络层缓存的首要目的,从访问效果来说客户端浏览器如果开启了缓存功能,当请求一张图片时,将从服务端上得到图片信息(CDN相对于浏览器来说就相当于服务器了),HTTP的返回代码就是200;当第二次请求同一张图片时,浏览器会自行判断在缓存区中的图片是否过期,就是判断HTTP协议中的max-age/Expires属性,如果没有过期就直接到浏览器缓存中取得原始图片(如果发现过期就请求服务器,不过这时服务器发现资源没有改变,就会给客户端一个HTTP 304的代码,提示浏览器可以继续使用本地缓存)。CDN的作用是解决服务端到客户端的最后一公里问题,当客户端向CDN请求图片时,CDN会到“离客户端最近的”服务节点去的图片信息,如果那个服务节点上没有相应的图片,CDN才会到真实的图片服务上提取图片并备后续使用。

    • 拦截/缓解单个图片服务节点上的请求压力:在真实服务之前的路由层缓存,主要起到的就是这个作用。以Nginx上的proxy_cache为例,我们一般基于它使用内存 + 物理磁盘的方式缓存多种没有过期的静态文件资源,包括图片文件。

    • 分散真实图片服务节点上的请求压力:路由层上除了缓存功能外,还起到分散请求压力的作用。无论技术团队在路由层使用的是Nginx、Haproxy或者是Spring Cloud——Zuul,要达到的一个目的就是对下层多个图片服务节点做请求负载。由于路由层的定位问题,所以一些图片服务系统中即使路由层没有提供缓存功能,但也一定会提供负载功能用来分散请求压力。

    总的来说多级服务缓存以最终以缩短客户端响应时间,减少图片服务器上真实的物理I/O操作压力为最终目的,经过多级缓存逐级削减向下传递的请求规模达到这样的目的。最终传递到最后一级业务层时,可能只剩下10%——30%的请求数量需要做真实的I/O操作(这还要看各级缓存的选型和详细参数设置)。而作为最后一级缓存的选型,除了读写速度上的要求外还有存储规模上的要求,所以Redis是一个比较理想的选择——利用Redis原生的Cluster技术,既可以兼顾访问速度、稳定性还可以获得很灵活的容量扩充方式。关于Redis Cluster的介绍可参考我另一篇文章《架构设计:系统存储(18)——Redis集群方案:高性能

    对缓存模块的设计和选型非常考量架构师对系统的驾驭能力。举个例子,为了保证数据A在靠近客户端的缓存模块失效时,数据A的访问压力不会直接传导到最后端的I/O请求上,就要保证数据A在下一层缓存上在同一时间不会失效。基于这样的考虑架构师可能需要配合调整每一层的缓存过期时间,否则就可能出现数据A在最上层缓存失效的同时,所有层级的缓存都已经失效,数据A不得不直接在真实服务器的物理磁盘上重新读取,并重建每一级缓存的情况。但问题是,如果数据A的更新时间设置得过长,且每一级缓存的有效时长依次增大,那么在数据A真正发生变化后,这个变化可能需要很长时间才会体现在客户端上。所以并不是缓存层级越多约好,也不是缓存上的数据过期时间越长约好

    3-3、路由层选择

    在图片服务系统中,路由层有两个作用:缓存和负载均衡。这两个作用的介绍已经在3-2小节中已经给出了一个概要说明,这里就不再进行赘述了。基于对上文中需求的考虑, 技术团队主要考虑在两种技术组件中进行选择,它们是Nginx和Spring Cloud——Zuul。本小节内容中我们主要对这两种技术对系统功能的契合度进行分析——它们在路由层分别使用时所基于的路由层功能定位完全不一样!Zuul是Spring Cloud服务治理框架(也称为微服务治理框架)的一个重要组件,它可以单独使用也可以和Spring Cloud中的其它组件集成使用。下表给出了Zuul和Nginx对于图片服务需求各个方面的契合度:

    组件NginxZuul目前图片服务中的要求
    缓存能力Nginx带有Proxy Cache模块,可以通过配置非常方便的进行数据缓存需要自行实现为了分散自上而下的数据请求压力,图片服务系统的代理层需要对数据进行缓存。后文还详细介绍这部分的考虑细节
    反向代理能力反向代理是Nginx的主要功能,配置灵活且性能优异有反向代理功能,虽然配置灵活性没有Nginx好,但是通过编程可以很方便的进行扩展没有特别要求
    路由能力支持基于正则表达式的路由功能配置自带路由配置功能,支持通配符形式的路由配置。还可以通过Zuul中的filters,扩展符合自身业务需求的路由规则没有特别要求
    负载均衡能力自带非常强大的均衡功能,支持基于正则表达式的负载均衡配置,支持多种负载均衡规则通过listOfServers关键字,可以配置负载均衡功能,但由于Zuul在Spring Cloud的定位问题负载均衡功能没有Nginx那么强大需要较灵活的负载均衡配置能力,对负载均衡功能的性能也有一定要求
    流量控制能力没有原生支持没有现成支持,但通过Zuul的filters规则可以通过编程非常方便的实现没有特别要求
    安全控制能力可以实现简单的安全控制功能,例如设置客户端黑白名单安全控制是Zuul的主要职责之一,通过Zuul的filters规则可以通过编程非常方便的实现,另外还可以直接集成Spring Cloud的安全控制组件Spring Cloud Security 来完成复杂的安全控制没有非常复杂的要求,后期可能需要对图片盗链问题进行控制
    监控和日志能力有日志功能,包括访问日志、拒绝日志、异常日志在内的多种日志,可以选择开启也可以选择关闭自带Log4j日志,通过结合Flume等数据汇聚组件可能非常方便的进行日志收集目前没有特别要求,不过后续版本中可能会要求
    编程扩展能力支持技术人员使用C/C++语言开发第三方Module,并在Nginx编译安装时一并安装。但实际情况是,大家都只会使用一些现成的Nginx Module本来就是Spring Cloud微服务治理框架的一个组件,支持使用JVM系列语言进行开发,您可以通过Zuul为代理层加入任何您想要的功能——如果不讨论软件解耦的科学性。没有特别要求

    (表完)

    从上表我们可以看出,Zuul和Nginx的功能虽然有一定的重合度,但是侧重点却是不一样的:Nginx倾向于配置,Zuul倾向于在特定规则下(filters责任链)自行编程实现,究其根本原因是两者的架构思路和在整体架构上存在的位置不一样。我们最终选择Nginx的原因实际上还是基于我们对路由层功能的定位:图片服务是单一的业务功能,并不存在再进行下层服务路由/代理的必要,所以没有必要使用Zuul提供的灵活路由规则支持。另外图片服务在至少能够预期的发展规划中并不存在很强的权限控制要求,即使有权限控制要求也是对图片盗链情况的控制,而图片盗链问题通过Nginx就可以很好的解决。最后,我们对路由层的功能定位主要就是缓存和负载均衡,而Nginx提供的负载均衡配置相对于Zuul提供的负载均衡更为灵活——这是因为Spring Cloud框架是一个服务治理框架,Zuul可以直接把请求转向Spring Cloud Eureka服务注册中心,而且Spring Cloud框架内部的负载均衡可以依靠Spring Cloud Ribbon完成。

    这里要特别讨论一下路由层的缓存控制问题。如果使用Nginx,那么可以使用它自带的Proxy-Cache功能建立运行的缓存空间;如果使用Zuul则需要自己通过代码实现一个缓存功能:

    这里写图片描述

    很明显基于Nginx的方案更方便,因为是现成的;使用Zuul的方案需要自行开发缓存功能,所以会有额外开发工作量(而且不小,看实现到什么程度),却更能契合功能要求。那么实际情况是什么呢?实际情况是我们还需要考虑对缓存状态的控制力度

    使用Nginx的Proxy-Cache虽然方便,但是它是独立工作的,只能按照配置好的方式载入载出数据资源。也就是说,当图片文件真正发生变化时我们无法通过Nginx提供的原生API接口,清除Nginx上相应的缓存数据。幸运的是,Nginx提供了一个可选模块proxy_cache_purge,通过HTTP请求的方式清空缓存,但这种主动清理方式在高并发情况下的性能并没有太多可靠性和性能方面的资料可查。这些还是其次,最重要的情况是我们无法在图片A变化时,准确知晓上层若干台设定了Nginx_Cache的Nginx中哪些Nginx节点需要刷新缓存。所以最后得出的路由层结论是:Nginx存在的主要作用是负载均衡,可以为它配置Proxy-Cache模块,但是不能设置过长的有效时长,可以设置成10分钟但绝对不能设置成10小时。这样才能保证下层图片数据发生变化时,客户端被延迟通知的时间更短。

    Nginx和Zuul 设计之初就针对两种不相同的业务领域,其功能定位和要解决的业务问题也是不一样的。之所以在路由层的技术选型中,比较这两种组件的差异,除了因为两者在功能上有一定的重合度外,更重要的原因是:功能/业务要求决定技术选型,而不是反过来进行思考

    3-4、设计细化

    基于以上所描述的各种技术关键点的选型,最终我们可以将概要的架构设计进行细化了。如下图所示:

    这里写图片描述

    上图中,最外层面向客户端访问加速的智能DNS路由、CDN加速服务通过购买获得(目前市面上还有很多免费的服务可以使用),首先这些组件与图片服务的核心设计基本上没有什么关联,其首要目标是加快客户端的服务响应速度,另外这样做还可以有效减少运维团队的工作量。至于LVS组件,可以和其它独立工作的子系统共享使用。

    我们最终采用Nginx作为图片服务的路由层,使用Nginx提供的负载均衡配置将数据请求压力分散到下层的多个服务节点上。使用Nginx原生的Proxy Cache作为处客户端缓存、CDN加速以外的第三级缓存,但不能将过期时间设置的太长(几分钟最合适)。如果图片发生的变更,也不能主动由业务节点基于proxy_cache_purge主动向Nginx通知删除缓存内容,因为根本不知道哪些Nginx节点需要被通知。类似图片文件访问频度这样的统计工作也在这路由层完成,只不过它不是由路由层本身来处理,而是使用类似Flume这样的日志收集组件对Nginx的access.log文件数据进行收集后,送至专门的日志分析系统完成。

    为了提高业务层的开发过程这次演示的开发工程将基于Spring Boot进行构建和代码编写,为了让图片文件的处理操作更加灵活,我们将基于责任链模式构建生产线形式的图片处理过程。我们还将在业务层使用Redis Cluster构造最后一级缓存,这级缓存的过期时间是各层缓存中最长的,存储规模也是各层缓存中最大的。一旦图片文件被更新后,业务层服务将直接使用Redis的原生JAVA API删除缓存中对应的数据信息。

    最后,持久层的分布式文件系统我们选用Ceph。实际上这一层可用的选型是最多的,只要把握两个规则就行:相同的内存空间中可以存放更多的元数据,存储小文件时浪费的空间更少。您还可以选用TFS、FastDFS,又或者直接使用网络块存储方案——光交换机 + 磁盘柜。

    =============================================

    (接后文)

    展开全文
  • 第三个 是SD卡 因为SD卡的读写速度较慢,如果将系统写入SD卡将大大影响我们的系统流畅程度 第四个 是Camera与WIFI接口,并且预留了一组GPL,这样我们就可以使用GPL挂载一些其他的外设,比方sensor红外

    一、一套最基础的安卓设备(开发版)应包含的组件

    这里写图片描述

    二、芯灵思开发板预览

    这里写图片描述

    第一口 UART ,这个比adb命令更加方便我们的工程师去抓取一些log
    第二个 是LED灯
    第三个 是SD卡 因为SD卡的读写速度较慢,如果将系统写入SD卡将大大影响我们的系统流畅程度
    第四个 是Camera与WIFI接口,并且预留了一组GPL,这样我们就可以使用GPL挂载一些其他的外设,比方sensor红外之类的
    第五个 是一个网线插口,这个开发板并没有直接提供WIFI
    第六个 这里提供了一个OTG和两个USB接口
    第七个 是LCD和HDMI接口

    核心区域

    1.主CPU A31S
    2. DDR 1G
    3.我们的FLash 也就是我们的EMMC 16G
    4.这就是我们的PMU 电池管理芯片

    这就是一块最简单的开发板外围接口和核心部分的简介

    三、Android整个系统架构和分层

    这里写图片描述

    1.Android整个系统是由软件和硬件组成的

    硬件第一个是指我们的主CPU,主CPU里有cache有MMU还有GPU和各种总线,这是由CPU的开发商给我们准备的。
    手机芯片开发商有 高通-骁龙系列、联发科-MTK系列、海思-麒麟系列
    当我们拿到一款CPU,了解到它的,基本接口之后,我们就需要拿它去做一些外围的设计
    我们所说的外围的设计包括:Sensor的造型、Camera的造型、LCD WIFI等等以及存储空间的大小,这些都是由我们硬件工程师来决定的,但是我们的软件工程师也会给一些参考意见,当我们把整个硬件确定完之后,我们再来看软件方面的工作。

    2.软件的工作从底层到上层可以分为这么几个部分

    第一个是Uboot
    第二个是内核
    第三个是Android OS
    Uboot的作用就是引导内核的启动,它首先会把我们的内核从FLash中搬到内存中引导内核启动
    有这么一个问题,Uboot是如何被引导的呢?
    这个由主CPU完成的,cpu里也会有一段引导程序,并且有一段固化的ROM,这个是由芯片厂商来完成的,我们的芯片提供厂商通常都会给我们提供几种启动模式,从USB启动,从SD卡启动或者从FLash启动,如何启动也是有它几个GPL的电频来决定的。
    比如我们把它固定的GPL进行上拉或者下拉就可以配对成这种选择
    如果我们配置从Flash启动,那么当我们双亮的时候,我们这一段引导程序就会从Flash中去引导我们的Uboot,从而完成我们Uboot的启动

    3.内核是整个系统的核心

    内核负责我们进程的管理,内存的管理,网络的管理,它可以直接对我们的硬件进行控制,并且把我们的硬件全部抽象成文件,对上层提供接口,当我们内核启动完成之后,就会根据我们所设置的参数去启动android系统

    4.Android软件层分层

    第一个是我们的Hal层
    第二个是我们的Framework(C++)层
    第三个是我们的第三方的一些库文件
    第四个是我们的虚拟机系统
    第五个是我们的Framework(Java)层
    第六个是我们的应用层
    其中HAL层的主要作用就是把我们的一些主要外设抽象出一套标准的接口供我们的Framework(C++)层调用。
    比方说我会把我们的Camera抽象出来一套接口,如果说我们的底层换了Camera之后呢,我们Camera和C++ Framework层它们之间的接口是不会发生改变的。我所要修改的就是Hal层调用我们驱动的方式会发生一些改变,但是Framework到Hal层他们之间的接口是不会改变的
    我们的Framework C++层主要是起一个承上启下的作用,对上也就是 Framework Java层,它提供服务,对下它能够挂接我们的Hal层,比如说我们的Camera Sensor Audio WIFI等外设,并且对我们这些外设提供一个保护,比如说我们上层有两个程序同时对Camera进行访问,但是呢,我们这里同一时刻只能有一个应用对我们的Camera进行访问,那我们的Framework现在就会有一种机制去管理这种访问确保在同一时刻只有一个应用程序对我们的Camera进行访问。

    5.三方库

    Android是一个庞大的系统,它同时引入了很多第三方开源的库。比如说LibJPerk,LibJPng,Scaya,Webkit等等,这些库也主要是为我们系统提供一些处理。

    6.Dalvik虚拟机

    Dalvik虚拟机主要是连接我们上层应用,我们底层的服务,我们的第三方库,提供一个自动化的管理尤其是我们的内存的一个管理。
    有了Dalvik虚拟机虚拟机之后,我们就可以使用Java去写我们相关的应用,我们用Java写应用的效率和代码的复用性要比C和C++高很多。

    7.Framework(Java)

    Framework(Java)层为我们提供了ActivityManager,WindowsManager,PackageManager,SensorManager等并提供了电源管理。WIFI管理等一系列的服务,并且Android还提供了相关的Activity以及进程间通讯的一些方式。
    这些Activity通讯的方式,管理系统和服务足够支撑我们快速的创建出我们自己的应用,并且这些代码全是开源的,我们也可以根据自己的需求去定制我们所需要的控件。

    8.App应用层

    我们的应用是基于java来实现的,运行在我们的虚拟机上,而且我们每一个进程对我们的访问权限也是有要求的。

    9.以Camera为例分析应用从上到下的代用顺序

    我们的应用程序想要拍张照片,首先,它要去获取我们的Camera服务,那么就会从我们的应用层调到我们的Framework java层,Framework java层通过虚拟机直接获取我们的Camera服务。
    如果当前我们的Camera服务有人在占用,那我们就会断开当前的连接,同时和我们新的应用建立一个连接,这样我们的应用就能获取我们Camera的访问权限,并且获取我们Camera获取的一些属性。
    然后我们的Camera服务和Hal层建立了关系。这样当我们点击一个拍照命令,那么我们的命令一直会从上层到我们的CameraService告诉我们的Camera Hal层。
    Hal层就会直接调用我们的驱动去控制我们的硬件去抓拍一张照片,我们的照片拿到的数据就会经过我们ISB处理然后返回给我们的Camera Service,再从Service通过我们的Dalvik虚拟机传递给我们上层。
    然后我们上层拿到图片就可以做一些处理,比方说做一些预览,或者直接存储到我们的Flash或者SD卡中。

    这就是android每层和每层之间的一个大概的联系

    四、Android系统启动过程

    这里写图片描述

    首先是上电
    接下来是bootloader,这个bootloader是生产时就已经烧录好的,它会根据我们的硬件以及GPL的设置来判断我们的系统是在U盘还是在SD卡以及我们的UFlash中启动
    去引导我们的Uboot
    我们的Uboot主要是初始化一些相关的外设,比方说内存,我们的Flash,以及我们CPU的一些IO,并且通过串口给我们提供一些修改启动参数的配置过程并且根据我们所配置的一个参数去引导内核启动。
    当我们的内核被引导起来之后,内核还是初始化一些外设,比方说我们的系统的一个主频,我们内存,我们Flash,我们的系统驱动,我们的外设驱动统一都被加载起来,并且根据我们Uboot的配置参数启动系统
    当我们的系统被起来之后,也就是我们的Android被起来之后,要进行一些列的初始化工作
    第一个是挂载分区,创建android一系列的目录
    创建目录后会1加载一些必要的驱动,加载完驱动之后根据我们的启动脚本去启动我们的系统服务,比如说mediaService,serviceManger,adbd。。。。。或者说我们自己新加的一些服务都会在这里启动。
    启动完之后它还会做一些相关的环境变量的配置,这些配置会在系统中启用,比如说我们的硬件版本,软件版本都会在这里进行设置,最后我们把所有的服务启动完之后,android启动服务就会在这里守护整个系统。
    如果说我们有个服务中间出现错漏,那我们的守护进程就会重新创建这个服务

    android启动时间是比较长的,就这三块(uboot,kernel,android)根据log周期看一下哪块比较耗时,根据自己和厂商的支持,针对某一模块做优化

    展开全文
  • Linux系统启动流程及系统裁剪

    万次阅读 多人点赞 2016-12-02 19:17:17
    Linux系统启动流程,Linux系统裁剪

    一、内核管理简要理论

    1、内核的功能
    (1)进程管理
    (2)内存管理(内核管理代码中代码量最大的部分)
    (3)I/O管理:中断及中断处理
    (4)文件系统:ext3,ext4,reiserfs,xfs等。。
    (5)驱动程序
    (6)安全相关:SELinux

    2、内核设计流派
    (1)单内核:单一体系结构(Linux)
    <1>特点:
    ①模块化设计:核心+外围功能性模块组成
    ②内核支持动态装卸载模块

    (2)微内核:内核子系统,更容易用于多线程编程(Windows、Solaris)

    二、Linux系统的初始化流程

    1、系统启动流程总结
    (1)
    POST(Power on self Testing)
    –>BIOS(boot sequence)
    –>GRUB(bootloader),分两阶段{stage1:在MBR中。stage2:在grub目录中}
    –>Kernel(找到initrd,被打包的模块)
    –>SHELL

    2、POST(Power on self testing)的作用
    (1)打开电源后,检测硬件设备是否正常工作。

    3、BIOS的作用
    (1)若电脑有多个存储设备,BIOS就会按照中的Boot Sequence(启动队列)来选择MBR所在的存储设备。

    4、GRUB(Grand Unified Bootloader)
    (1)1st stage(第一阶段):位于MBR中,为引导2nd stage。
    (2)1.5 stage:位于boot基本磁盘分区中,为识别内核文件所在的文件系统提供文件识别扩展。
    (3)位于boot基本磁盘分区中,GRUB的引导程序。

    5、启动kernel
    (1)启动vmlinuz,vmlinuz是一段压缩存放的代码,分为两端,一个解压代码,一个为内核代码。
    (2)vmlinuz一般在boot目录下。
    (3)vmlinuz完成对内核的初始化

    (4)内核初始化时候需要启动用户进程:/sbin/ini,需要/lib/modules中的内核模块,但内核模块在根分区上,vmlinuz识别/分区又需要内核模块。(鸡和蛋问题)
    <1>解决方案:安装操作系统的时候,安装程序能识别内核模块所在磁盘,并将内核模块打包为initrd供vmlinuz识别使用。

    6、用户空间进程/sbin/init启动以后的工作
    (1)执行/etc/rc.d/rc.ssysinit脚本完成系统初始化工作

    三、系统裁剪流程详解

    1、系统裁剪要求:有GRUB引导系统,并且使用init脚本实现网卡驱动的装载,以及IP地址的配置,添加tserver服务,并在系统启动时启动此服务并显示。

    2、操作环境的目标
    (1)在vmware12中操作,系统为Centos6.5
    (2)基于宿主机(Host)制作一个简单可启动的Linux

    3、流程概括
    (1)为虚拟机添加一块新硬盘,并为其分区,安装GRUB
    (2)复制内核文件(vmllinuz)和initrd文件至新硬盘中。
    (3)移植bash,网络相关命令ifconfig、ip、ping命令,文件列表命令ls,服务管理命令chkconfig,模块装载卸载命令insmod、rmmod,挂载卸载命令mount、umount,文件查看命令cat至目标主机(Target)的/文件系统中。
    (4)为grub提供配置文件。
    (5)为目标主机配置/sbin/init文件启动网络服务和其他服务。
    (6)将目标主机的硬盘装载其他电脑上。

    4、添加新硬盘并分区、格式化和挂载
    (1)在虚拟机上添加一块20G的硬盘,名为TinyLinux。
    这里写图片描述

    (2)为硬盘分区{一个为500M(boot分区),一个为1G(/分区)}

     # fidk /dev/sdb

    这里写图片描述

    (3)检查分区是否成功

    # partprobe /dev/sdb
    # cat /proc/partitions

    这里写图片描述

    (4)分区格式化

    # mke2fs -t ext4 /dev/sdb1
    # mke2fs -t ext4 /dev/sdb2

    这里写图片描述

    (5)在/mnt目录下创建boot目录以及sysroot目录,并将上面两个文件系统进行挂载。

    # mkdir /mnt/{boot,sysroot}
    # mount /dev/sdb1 /mnt/boot
    # mount /dev/sdb2 /mnt/sysroot
    # mount

    这里写图片描述

    5、安装GRUB
    (1)安装命令grub格式:
    # grub-install –root-directory=(boot所在目录) /dev/sd[a-z]
    (2)例:

    # grub-install --root-directory=/mnt /dev/sdb

    这里写图片描述

    6、复制内核文件和initrd文件至目标主机磁盘
    (1)内核文件为宿主机中的/boot/vmlinuz-VERSION
    (2)initrd文件为宿主机的/boot/initramfs-VERSION.img
    (3)复制示例:

    # cp /boot/vmlinuz-2.6.32-431.el6.x86_64 /mnt/boot/vmlinuz
    # cp /boot/initramfs-2.6.32-431.el6.x86_64.img /mnt/boot/initramfs.img
    # ls /mnt/boot
    

    这里写图片描述

    7、创建目标主机的根文件系统
    (1)根文件系统一般包含的目录:
    etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,srv,mnt,media,root
    (2)示例:

    # mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,srv,mnt,media,root}

    这里写图片描述

    8、移植bash等命令至目标主机根文件系统
    (1)移植的时候需要把命令的可执行文件以及所依赖的库文件复制,命令才能被执行。
    (2)可执行文件位于/bin目录下,库文件在/lib目录 或者/lib64目录下。
    (3)用which COMMAND 命令可查看命令的执行文件在哪个位置
    ldd `which COMMAND`命令可查看命令所依赖的库文件在哪个位置。

    (4)用一个脚本实现将命令的可执行文件以及其所依赖的库文件复制到目标主机根文件系统中

    #!/bin/bash
    #
    target=/mnt/sysroot
    
    clearCmd(){
    if which $cmd &> /dev/null;then
    cmdPath=`which --skip-alias $cmd`
            else
                 echo "No such command"
                return 5
            fi
    
    }
    
     cmdCopy(){
             cmdDir=`dirname $1`
            [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir}
            [ -f ${target}${1} ] && echo -e "\033[31mThe ${1} exist!\033[0m" && return 5
            [ -f ${target}${1} ] || cp $1 ${target}${cmdDir}
            echo -e "\033[32mCopy ${1} success.\033[0m"
    }
    
    libCopy(){
            for lib in `ldd $1 | grep -o "/[^[:space:]]\{1,\}"`;do
                    libDir=`dirname $lib`
                    [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}
                    [ -f ${target}${lib} ] && echo -e "\033[31mThe ${lib} exist!\033[0m" && continue
                    [ -f ${target}${lib} ] || cp $lib ${target}${libDir}
                    echo -e "\033[32mCopy ${lib} success.\033[0m"
            done
    
    }
    
    while true;do
            read -p "Enter a command: " cmd
            if [ "$cmd" == "quit" ];then
                    echo "quit"
                    exit 0
            fi
            clearCmd $cmd
            [ $? -eq 5 ]&& continue
    
            cmdCopy $cmdPath
            libCopy $cmdPath
    done

    (5)复制示例:

    # bash /root/scripts/cpcmd.sh
    
    bash
    ls
    cat
    insmod
    rmmod
    mount
    umount
    ifconfig
    ip
    ping
    chkconfig
    

    这里写图片描述
    这里写图片描述
    复制成功。

    9、为提供配置文件
    (1)示例:

    # vim /mnt/boot/grub/grub.conf
    内容为:
    default=0
    timeout=5
    title Tiny Linux
            root (hd0,0)
            kernel /vmlinuz ro root=/dev/sda2  quiet selinux=0 init=/bin/bash
            initrd /initramfs.img

    (2)字段解释:
    <1>default =# :指定默认启动的内核或者OS(Operating System)
    <2>timeout=# :等待用户选择要启动的内核或OS的时长,单位为秒。
    <3>splashimage=/path/to/splashimage_file :指定使用的背景图片
    <4>hiddenmenu:隐藏菜单
    <5>tittle

        root (Device(磁盘设备),Part(磁盘分区) )
            ①Device表示方式:在grub中,统统以hd开头,并紧跟一个数字做各磁盘设备的标志,从0开始编号。
            ②Part表示方式:代表分区,从0开始编号
    
        kernel 
            ①指定内核文件及传递给内核的参数,常用参数:ro root=/path/to/device,
            表示把该设备文件所表示的设备当作内核去挂载时的根使用的真正根分区所在的设备。(只读挂载) 
            参数格式:ro root=/path/to/device quiet
            quiet为静默模式
    
        initrd
            ①文件通常为cpio归档,并使用gzip压缩;通常以.img作为文件后缀名(映像文件)
    

    10、将目标主机的硬盘装载其他电脑上。

    切记在装载前先把宿主机挂起,再装载在其他电脑上,以免数据被损坏。
    (1)在vmware12中创建一个新的虚拟机,内核为64位即可,一下是我自己的配置:
    这里写图片描述

    (2)为该虚拟机提供硬盘,在Centos6.5目录下找到TinyLinux.vmdk文件即可
    这里写图片描述
    这里写图片描述

    (3)启动该虚拟机,若有grub引导并出现如下界面,并且命令正确,证明TinyLinux小系统能成功运行。

    这里写图片描述

    这里写图片描述

    11、复制网卡模块至目标主机的
    (1)网卡模块所在路径:
    /lib/modules/2.6.32-431.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
    (2)创建/mnt/sysroot/lib/modules目录

    # mkdir /mnt/sysroot/lib/modules

    (3)复制网卡模块至/mnt/sysroot/lib/modules目录下

    # cp /lib/modules/2.6.32-431.el6.x86_64/kernel/drivers/net/e1000/e1000.ko /mnt/sysroot/lib/modules/

    这里写图片描述

    12、为目标主机配置/sbin/init文件启动网络服务和其他服务
    (1)将上面步骤中开启的新的虚拟机关机,重新打开挂起的Centos6.5
    (2)编辑/mnt/sysroot/sbin/init文件

    # vim /mnt/sysroot/sbin/init
    
    编辑内容:
    #!/bin/bash
    #
    echo -e "\tWelcome to \033[34mKingOlie Tiny \033[0mLinux"
    mount -n -t proc proc /proc
    mount -n -t sysfs sysfs /sys
    insmod /lib/modules/e1000.ko
    [ $? -eq 0 ] && echo -e "Loaded e1000 module \033[60G[ \033[32mOK\033[0m ]"
    ifconfig lo 127.0.0.0/8
    ifconfig eth0 172.17.45.243/24
    mount -n -o remount,rw /dev/sda2 /
    /bin/bash
    # chmod  +x /mnt/sysroot/sbin/init
    谨记必须给init脚本加上执行权限,否则系统启动的时候并不会执行init,会出现kernel panic错误。
    # sync
    使用sync将内存写入的数据同步到磁盘中去。可以使用多次,以确保文件数据已经被同步到磁盘中。

    (3)编辑/mnt/boot/grub/grub.conf文件,将init指定为sbin目录下的init

    (4)如果目标主机启动时候显示绿色OK字样,证明网卡模块已经被装载。
    这里写图片描述

    (5)用ping命令检验网络模块能否正常工作

    # ping 172.17.45.243
    此时,ctrl+c按键并不能中断ping命令,因为该小系统并没有配置ctrl+c热键。
    建议使用以下命令限定ping次数和时间检测:
    # ping -w 5 -c 5 172.17.45.243

    这里写图片描述

    ===================================================

    以上是我的个人总结,如有错误,欢迎大家指出,谢谢大家。

    展开全文
  • 因此很多网站都会将图片存储从网站中分离出来,另外架构一个或多个服务器来存储图片,将图片放到一个虚拟目录中,而网页上的图片都用一个URL地址来指向这些服务器上的图片的地址,这样的话网站的性能就明显提高了,...

    1 介绍

    现在很多的网站上都会用到大量的图片,而图片是网页传输中占主要的数据量,也是影响网站性能的主要因素。因此很多网站都会将图片存储从网站中分离出来,另外架构一个或多个服务器来存储图片,将图片放到一个虚拟目录中,而网页上的图片都用一个URL地址来指向这些服务器上的图片的地址,这样的话网站的性能就明显提高了,图片服务器(ImageServer)的概念也就产生了。

    1.1 图片服务器的优势

     

    1, 分担Web服务器的I/O负载-将耗费资源的图片服务分离出来,提高服务器的性能和稳定性。

    2, 能够专门对图片服务器进行优化-为图片服务设置有针对性的缓存方案,减少带宽成本,提高访问速度。

    3, 提高网站的可扩展性-通过增加图片服务器,提高图片吞吐能力。

     

    1.2 图片服务器的注意事项

    1, 选择适合图片存储的物理介质和文件系统

    2, 使用物理上独立的服务器

    3, 如果拥有多台图片服务器,要考虑服务器之间的图片同步问题

    4, 使用独立域名

    5, 制定合理的缓存策略

    6, 使用图片处理模块对用户上传的图片进行再加工

    1.3 图片服务器的架构

    图片是网站中必不可少的一个组成部分,随着网站的不断发展,对图片的处理也将随着访问的增长,图片的增加提出不断改进的需求, 网站初期,所有的一切都从简图片所存在的位置通常会在站点下的Images文件夹。

    随着访问的增加,IIS压力的增大,开始做拆分,将图片文件夹作为单独站点提取出来如http://images.***.com/(可能根据需要会拆分成多个图片服务器,与具体业务环境相关),拆分之后很好的将单个IIS应用池的压力分担到2个乃至多个上,大大提高访问瓶颈。随着访问的进一步增加,服务器压力已经无法支撑,这时我们需要将图片站点作为独立服务器存在。在访问图片的过程中,我们可能会面临一个图片有多个图片尺寸的需求,前期我们通常会在保存页面的过程中保存我们需要的各个尺寸图片,但随着所需尺寸的不同,保存图片时需要的尺寸越来越多,这时我们如何应对?

    IIS服务器的并发访问意味着随着用户的进一步增加,我们单台图片服务器已经不足以应对了,此时我们如何进一步扩展?


     

    如上图所示,我们此时可针对这两个问题做出统一解决方案,在前端添加squid缓存服务器,添加一台或者多台动态切图服务器。Squid或者Nginx代理缓存服务器能够极大的提升图片系统的并发访问,使系统突破现有限制。动态切图服务器主要的作用是针对不同尺寸的图片访问调取原图临时生成符合需求的图片并返回。原图的存储区可以与图片服务放在一起,也可以讲图片放于单独的服务器上。

    在此种结构中,并发的最大访问限制将是squid或者其他代理服务器的系统瓶颈,当切图服务压力增大时,只需添加相应切图服务器即可,图片存储区的增长也可通过添加硬盘或者服务器进行解决。

    如果您的站点访问量还在进一步增长,squid的访问瓶颈即将被突破,这时我们又该如何应对呢?

     

    如上图所示,采用多台Squid或Nginx服务器,在前端添加F5或LVS负载均衡(同时还可开启缓存功能)。此时将极大提升访问的并发量,可以根据情况随时调配服务器。当然此时也存在一定的瑕疵,那就是可能在多台Squid上存在同一张图片,因为访问图片时可能第一次分到squid1,在F5过期后第二次访问到squid2或者别的,当然相对并发问题的解决,此种少量的冗余完全在我们的允许范围之内。在做了这许多的工作后,如果条件允许对图片服务器做下CDN,那将会对您站点的图片访问质量有更大的提升。

     

    1.4 图片存储架构

    1.4.1 部署独立图片服务器的必要性

    我们知道,无论对于Apache还是IIS,图片始终是最消耗系统资源的,如果将图片服务和应用服务放在同一个服务器的话,应用服务器很容易会因为图片的高I/O负载而崩溃,因此对于有些大型网站项目,我们有必要将图片服务器和应用服务器分离。部署独立的图片服务器(甚至是服务器集群)是大型网站图片存储解决方案中最基础的,因为有了独立的图片服务器后,我们才能对图片服务器做更有针对性的性能优化,比如从硬件角度说,图片服务器可以配置高端的硬盘,7200转的换成15000转的,而CPU却只要一般就可以了;从软件角度说,可以为图片服务器配置特殊的文件系统来满足对图片的I/O请求,如淘宝的TFS,就很好地解决了大规模小图片文件带来的I/O噩梦,同时,我们也可以采用nginx、squid来代理图片请求等等。

     

    1.4.2 采用独立域名

    注意,这里是指独立域名,不是子域哦,比如yahoo.com图片服务器用了yimg.com的域名,而不是用二级域名img.yahoo.com,这是为什么呢?个人觉得原因主要有以下几点:

    1、同一域名下浏览器的并发连接数有限制,一般在2 - 6之间,下图列举了各个浏览器的并发连接数(下图供参考)

        

    这样,我们如果给图片服务器配置独立的域名,那么在一个页面中加载图片时,就可以突破浏览器连接数的限制,理论上,增加一个独立域名,并发连接数加倍。

    2、由于cookie的原因,对缓存不利

    比如有一张图片http://www.test.com/img/xx.gif,那么当我们向它发起请求的时候,会带上www.test.com域名下的cookie,由于大部分web cache都只缓存不带cookie的请求,这样就导致每次的图片请求都不能命中cache,而仍旧要去原始服务器获取图片,导致图片缓存意义不大。所以,还是给单独搞一个图片独立域名吧,当然,不只是图片,css和js文件也可以参照这个思路来搞。

    3、方便CDN同步

     

    1.4.3 图片服务器分离后,如何进行图片上传和图片同步

    当然任何事物都具有两面性,图片服务器分离固然提升了图片访问的效率,大大缓解了服务器因图片造成的I/O瓶颈,但是分离以后图片的上传和同步就成了一个大问题了。下面就我个人的想法谈谈几种解决方案。

    1、NFS共享方式

    如果你不想在每台图片服务器同步所有图片,那NFS共享是最简单也最实用的方式。NFS是个分布式的客户机/服务器文件系统,NFS的实质在于用户间计算机的共享,用户可以联结到共享计算机并象访问本地硬盘一样访问共享计算机上的文件。

    具体实现思路是:web服务器通过nfs挂载多台图片服务器export出来的目录,用户先将图片上传到web服务器,然后将上传的图片通过程序拷贝到这个mount目录中去,这样那几台图片服务器就也能访问到刚上传的图片了(注意,只是共享了,并没有真正拷贝到图片服务器)。再给那几台图片服务器绑定独立域名,于是浏览器端就可以用单独的域名来访问图片了。这种方式基本不会有因同步造成的延时,但需要依赖nfs,nfs挂掉会影响web服务器。如下图


    至于如何配置nfs,大家google一下,或者看一下这篇文章,是在Linux下配置NFS的http://blog.csdn.net/lixinso/article/details/6639643

    2、利用FTP同步

    和上面nfs不一样的是,用户上传完图片后是利用ftp同步到各个图片服务器的,php、java、asp.net基本上都能操作ftp。这样的话每个图片服务器就都保存一份图片的副本,也起到了备份的作用。但是缺点是将图片ftp到服务器比较耗时,如果异步去同步的话又会有延时,不过一般的小图片文件也还好了。

     

    2 图片服务器的URL HASH架构剖析 

    2.1 什么是url hash 架构

    url hash架构对url进行一次hash算法,然后通过hash结果找到对应的服务器。因为针对单一个url的hash结果是一样的,所以理论上这个url会被永久分配到固定的一台服务器上。另外因为经过了hash算法,所以分配url就很均匀,同时访问量也可以达到均衡。

     

    2.2 为什么要用url hash架构 

    1, 图片服务器的特点一是访问量很大,二是容量也很大,通过简单的负载均衡,可以解决访问量大的问题,但是容量的问题并没有改善。所以会造成容灾问题。

    2, 容灾问题:系统某个时间段被访问的数据严重超出缓存集群中最小单机的容纳容量就会造成容灾,容灾会使大量单一链接穿透,直接对后台的IO性能影响很大。

    3, 虽然可以通过增加缓存容量的配置来解决容灾问题,但是内存总是有限的,为每一台机器增加超大内存成本上也开销很大,另外在squid中也不宜配置很大的磁盘缓存,否则squid中的hash表会很大,性能很差。

    4, 通过hash架构,可以充分利用缓存集群的内存,容灾问题就不再取决于缓存集群中最小单机的容纳容量,而是缓存集群中所有机器的容纳容量之和。

    2.3 各种url hash架构

    1)基于dns的hash架构。

    2)基于nginx的自动hash架构。

    3)基于nginx的手动hash架构。

     

    2.3.1 基于dns的hash架构

    dns的hash架构图

     

     

    dns的hash架构说明

    这个架构适合面向用户的图片系统,比如论坛、相册、博客中的图片上传。这样它才能够保证文件名有一致的规范。

    这个架构图分了36个域名,图片文件名是用md5值起的,在md5值中取一位字母就可以表明它是在哪个域名里,域名就对应了机器,上传分发的时候也是根据此字母来分发。

     

    dns的hash架构的优缺点

    优点:

    1)使用了dns分流,成本较低,而且dns性能高,不用维护。

    2)可突破IE默认每主机2个线程的限制。

    缺点:

    1)可用性方面,如果有一台机器宕机,则指向这台机器的请求无法读取。

    2)分流方面,只能全部同步,成本较高

    3)只适用于面向用户的系统

     

    2.3.2 基于nginx的自动手动hash架构

    nginx的自动hash架构图

     

    nginx的自动hash架构说明

    1, 这是一种新的缓存架构,由nginx作为最前端,代理到缓存机器。

    2, nginx后面是缓存组,由nginx经过url hash后将请求分到缓存机器。

    3, 这个架构方便纯squid缓存升级,可以在squid的机器上加装nginx

    4, nginx有缓存的功能,可以将一些访问量特大的链接直接缓存在nginx上,就不用经过多一次代理的请求。比如favicon.ico和网站的logo

    nginx的自动hash架构优缺点

    优点

    1)高性能

    2)使用方便,后台是什么样关系不大

    3)有很高的可用性

    4)缓存架构,分流方便

    5)可直接在nginx代理缓存部分链接

    缺点

    url分流可控性弱,增减缓存机器都会引起缓存重新分配,意味着缓存全部失效。

     

    nginx的手动hash架构说明

    1,这个架构图和自动hash的架构是一样的,唯一有差别的是hash算法的变化,自动hash是用nginx upstream hash模块自带的hash算法来实现分流,这个手动架构是自己设计一个算法来实现。

    2,算法设计思路是从url中取一个字符来作分流依据,比如定义链接的倒数第10个字符来分流,同样可以分配得很均匀。

    3,手动架构可以避免自动架构中增减机器带来的缓存失效问题,另外可以精确知道一个链接到底存在哪台缓存上。

     

    nginx的手动hash架构优缺点

    优点

    1)基本可以继承自动架构的优点

    2)避免增减机器的问题

    3)精确知道链接存储在哪台缓存上

    缺点

    配置较复杂,要分配均匀配置不易。

     

    采用Hash架构对bbs架构优化

     

    1,先前讲的bbs架构采用的是lvs+squid作为前端,这样的话squidclient更新缓存时需要更新所有的squid,这个效率很低下,使用hash架构就可以使squidclient每次只需要清理一台squid,效率大为提升。

    2,推荐的是使用nginx手动hash架构,它可以精确知道链接会存在哪台机器上,这样就可以配置精确的备份机器。

     

    3 nginx图片服务器的架构方案

    图片服务通常数据容量较大,而且访问也频繁,鉴于此,图片服务就会有两种问题,一是存储问题,二是访问量问题。
    存储问题就是硬盘容量问题, 花钱买硬盘就可以了,看似简单,但着实也是最苦的问题。按目前探索来看,最好的方式是:在任何时刻遇到硬盘空间不够时,买颗硬盘插上,最多改改配置,就能 立刻利用;另外,硬盘要能充分利用,不然图片存储量大再加上备份,很恐怖,最好是每颗硬盘都用上100%的空间。
    访问量也是个大问题,如 果服务不允许防盗链,那么访问量会引起带宽、服务器压力等问题,有钱的话直接扔CDN,没钱或者有更多的钱,就自己做吧。根据垣古不变的真理越老的图, 访问量也相对较少这一点,分成两大部分,一边处理最新的图片,一边处理老旧的图片。最新的图片访问量大,但存储量较少;老图片访问量低,但存储量大。

     

    3.1 拟定一个存储目录规则

    在现有的/a/b/abcde.jpg这样的hash方式下多加一个日期的目录变成:/200810/16/a/b/abcde.jpg或者/2008/10/16/a/b/abcde.jpg。按日期制定这个目录规则后,就可以按年月来拆机器了。

    3.2 分机器,分硬盘

    按之前的计划,分成两个组,一组服务器用lvs做负载均衡负责新图片;另一组服务器做旧图片访问和备份。新图机器找几台好点的服务器,SCSI硬盘;旧图机 器没太大要求,PC机就行,找够硬盘就可以,现在IDE1T硬盘也不太贵,最好再搭个raid就省事了,最主要是这些机器要多。如下图:

     

     

    说明一下:
    1、图片服务通过lvs作为入口,处理能力上还是有保障的。
    2、利用nginx直接对外服务,不必用squid
    3、图中的红线是指主nginx会将/2006/2007年的图片分别代理到两台存档服务器,如果发现主nginxcpu占用比较大,那么可以考虑使用nginxproxy_store将图片存到主服务器上,定期清理。
    4、图中有一台存储分配服务器,作为图片服务更新图片的统一入口,有新图片或者修改图片的话,由这台服务器负责将图片放到正确的服务器上去。
    5、旧图片服务器当前用年份来划分,每年增加两台服务器,亦可是加两块硬盘,注意,不要相信raid,一定要有两台机器,地理上分在两个城市则更好。
    6、因为旧数据20062007年的数据基本上是没有变化的,所以假如硬盘够大,那么可以把两年的数据合并在一起。
    7、如果细心定制,那么旧图片服务器的硬盘100%塞满是可以的,旧数据的容量基本上不会大幅增长,小小预留1-2G空间就可以了。

    展开全文
  • 笔记本电脑原本有一块装了win7的机械硬盘,后来在光驱处加装了一块固态硬盘,在固态上装了win10组成了双系统,开机顺序是先启动机械硬盘再启动固态硬盘,我现在想先启动固态硬盘再启动机械硬盘,但是这样无法启动...
  • 处理器、内存、系统: 硬盘:256G三星固态盘+2T希捷SATA机械盘 Win10已经安装在固态 安装流程 准备空闲分区 磁盘管理中选择压缩卷,固态还能分出150G左右给Ubuntu,另在机械盘分出了200G左右。硬盘分区如下(此为已...
  • EFI:支持EFI分区所要使用的引导程序 images目录:。 efiboot.img:用于支持EFI引导...initrd.img:虚根,临时根安装系统时将此文件展开放在内存中作为根,同时将vmlinuz也加载到这个根下完成系统创建。 vml...
  • VR系统组成

    千次阅读 2019-02-14 15:14:27
    一个典型的虚拟现实系统主要由计算机、输入/输出设备、应用软件和数据库等部分组成。 1.计算机 在虚拟现实系统中,计算机着至关重要的作用,可以称之为虚拟现实世界的心脏。它负责整个虚拟世界的实时渲染计算,...
  • 汽车悬挂系统的基本原理和构成

    千次阅读 2019-08-10 08:59:57
    【1】悬挂系统的基本构成 简单说来,汽车悬挂包括弹性元件、减振器和传力装置等三部分,分别缓冲、减振和受力传递的 作用。从轿车上来讲,弹性元件多指螺旋弹簧,它只承受垂直载荷,缓和及抑制不平路面对车体的 ...
  • 1、概述 图片服务系统是各种针对C端系统常见的子系统,它的特点是存储规模大请求...虽然由于写作计划的变化,图片服务系统中所涉及的分布式文件系统原理、非关系型数据库原理都还没有讲到,但这些知识点也并不是组成
  • Linux系统启动流程

    千次阅读 2013-08-23 15:47:19
    Linux系统启动流程 Linux系统启动流程如下 BIOSMBRGRUB加载内核initrunlevel BIOS BIOS(Basic Input Output System). 计算机启动的时候第一个运行的就是BIOS, BIOS负责检查硬件并且查找可启动的设备 常见启动设备...
  • 启动图片设置 类型 横竖屏 系统版本 屏幕尺寸 切图尺寸 命名规范(1,表示第一个版本,P竖屏L横屏) iphone6 plus 竖屏 ios8,9 RetinaHD5.5 1242×2208 Launch...
  • Android系统启动顺序

    2017-08-18 19:19:39
    Android是一个基于Linux的开源操作系统。x86(x86是一系列的基于intel 8086 CPU的计算机微处理器指令集架构)是linux内核部署最常见的系统。然而,所有的Android设备都是运行在ARM处理器(ARM 源自进阶精简指令集...
  •  在介绍软件运行流程之前,我需要先介绍以下内核中组成的子系统部分:  (1)系统调用子系统部分:这就相当与内核对外提供了一个调用其子系统的接口,用户进行需要执行一些内核权限才具有的操作时,就必须通过该...
  • STM32F103C8T6最小系统

    万次阅读 多人点赞 2019-07-09 23:25:17
    单片机最小系统一般有晶振电路、电源电路、复位电路以及调试电路组成。本文以STM32F103C8T6为例,介绍最小电路的设计和要注意的问题。
  • 一、Android系统启动 Android框架架构图:(来自网上,我觉得这张图看起来很清晰)   Linux内核启动之后就到Android Init进程,进而启动Android相关的服务和应用。启动的过程如下图所示:(图片来自网上,后面...
  • 操作系统是“中断驱动”的;换言之,中断(广义)是激活操作系统的唯一方式 中断有广义和狭义之分,上述中断时指广义的中断 【中断、异常与系统异常】 狭义的中断来源于处理器之外的中断事件,即与当前运行指令...
  • 摘要本报告介绍FreeBSD虚拟内存子系统启动过程。FreeBSD虚拟内存子系统是许多其他子系统的基础,譬如文件子系统、设备子系统、进程子系统等等,而且它与系统设备、体系结构密切相关,特别是从实模式到保护模式下的...
  • 这篇博客我们只从四个方面简单概括得说操作系统组成。这四个方面是计算机的基本组成、进程概论、内存管理和操作系统的发展。 一、计算机的基本组成 说到计算机的基本组成我们必须了解到一个人冯诺依曼。他是第一个...
  • 17.1 centos6系统启动过程及相关配置文件 17.2 centos7系统启动过程及相关配置文件 17.3 实战-加密grub防止黑客通过单用户系统破解root密码 17.4 实战-通过liveCD进入救援模式-重装grub修复损坏的系统 17.1 centos6...
  • 大家好,我是高胜寒,本文是Linux运维-循序渐进学运维-基础篇的第59篇文章 文章目录前言centos 6的启动过程1. 加载BIOS硬件信息a) 通电自检b) MBR... 登录系统启动完成启动相关的配置文件1. boot目录2. 运行级别总结
  • 例如,我们在进行设计时可以将图片访问的URL地址直接对应图片文件在服务器上的存储地址,并按照一定的规则将图片文件重命名成一个系统中唯一的文件名,最后再删除Redis和Nginx Proxy Cache中可能存在的历史文件数据...
  • 红帽系统开机启动流程

    千次阅读 2017-09-05 23:18:00
    # 启动系统默认使用的背景图片,背景图可以自己制作,640X480像素,使用14位色 splashimage=(hd0,0)/grub/splash.xpm.gz # 默认是隐藏菜单栏 hiddenmenu # 如果想使用grub命令启动,必须输入正确的密码 ...
  • 文件系统:ext3,ext4 驱动程序: 安全相关:SELinux 通用软件,平台类的软件 内核设计流派: 单内核:各功能做在一起,单一体系结构 Linux:虽然是单内核,但是采用了微内核的思想,模块化设置:核心+外围功能...
  • 宏观认识操作系统 什么是操作系统 操作系统可以干什么 开始进入操作系统 开机的一瞬间,电脑在干嘛 bootsect.s bootsect.s小结 setup.s setup小结 head.s main.c 总结 参考资料 宏观认识操作系统 什么...
  • 1)了解分布式文件系统的概念及应用场景 2)理解fastDFS的工作原理 3)掌握fastDFS存取文件方法 1 FastDFS研究 1什么是分布式文件系统 1.1技术应用场景 传智播客拥有大量优质的视频教程,并且免费提供给用户去下载,...
  • 嵌入式Linux系统主要特点在于使用Bootloader替代了桌面系统的BIOS,同时对系统进行了规模上的裁剪,但硬件上的劣势往往导致系统启动速度较慢,而嵌入式产品使用者又对系统的开机速度比较敏感,样就产生了对于提高...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 121,161
精华内容 48,464
关键字:

启动系统的组成图片