精华内容
下载资源
问答
  • 内存分段和分页管理方式和由此衍生一堆段页式等都属于内存不连续分配。什么叫不连续分配?就是把程序分割成一块一块装入内存,在物理上不用彼此相连,在逻辑上使用段表或者页表将离散分布这些小块串起来...

    内存的分段和分页管理方式和由此衍生的一堆段页式等都属于内存的不连续分配。什么叫不连续分配?就是把程序分割成一块一块的装入内存,在物理上不用彼此相连,在逻辑上使用段表或者页表将离散分布的这些小块串起来形成逻辑上连续的程序。
    在基本的分页概念中,我们把程序分成等长的小块。这些小块叫做“页(Page)”,同样内存也被我们分成了和页面同样大小的”页框(Frame)“,一个页可以装到一个页框里。在执行程序的时候我们根据一个页表去查找某个页面在内存的某个页框中,由此完成了逻辑到物理的映射。
    分段和分页有很多类似的地方,但是最大的区别在于分页对于用户来说是没什么逻辑意义的,分页是为了完成离散存储,所有的页面大小都一样,对程序员来说这就像碎纸机一样,出来的东西没有完整意义。但是分段不一样,分段不定长,分页由系统完成,分段有时在编译过程中会指定划分,因此可以保留部分逻辑特征,容易实现分段共享。

    要理解分段和分页,那么得理解为什么会出现分段和分页的技术。
    首先,这两个技术都是为了利用和管理好计算机的资源–内存。在分段这个技术还没有出现之前,程序运行是需要从内存中分配出足够多的连续的内存,然后把整个程序装载进去。举个例子,某个程序大小是10M,然后,就需要有连续的10M内存空间才能把这个程序装载到内存里面。如果无法找到连续的10M内存,就无法把这个程序装载进内存里面,程序也就无法得到运行。
    上面这种直接把整个程序装载进内存的方式是有一定的问题的。例如:

    1. 地址空间不隔离如何
      理解地址空间不隔离?
      举个例子,假设我有两个程序,一个是程序A,一个是程序B。程序A在内存中的地址假设是0x00000000~0x00000099,程序B在内存中的地址假设是0x00000100~x00000199。那么假设你在程序A中,本来想操作地址0x00000050,不小心手残操作了地址0x00000150,那么,不好的事情或许会发生。你影响了程序A也就罢了,你把程序B也搞了一顿。
    2. 程序运行时候的地址不确定
      如何理解程序运行时候的地址不确定?
      因为我们程序每次要运行的时候,都是需要装载到内存中的,假设你在程序中写死了要操作某个地址的内存,例如你要地址0x00000010。但是问题来了,你能够保证你操作的地址0x00000010真的就是你原来想操作的那个位置吗?很可能程序第一次装载进内存的位置是0x00000000~0x00000099,而程序第二次运行的时候,这个程序装载进内存的位置变成了0x00000200~0x00000299,而你操作的0x00000010地址压根就不是属于这个程序所占有的内存。
    3. 内存使用率低下
      如何理解内存使用率低下呢?
      举个例子,假设你写了3个程序,其中程序A大小为10M,程序B为70M,程序C的大小为30M。你的计算机的内存总共有100M。这三个程序加起来有110M,显然这三个程序是无法同时存在于内存中的。并且最多只能够同时运行两个程序。
      可能是这样的,程序A占有的内存空间是0x00000000~0x00000009,程序B占有的内存空间是0x00000010~0x00000079。假设这个时候程序C要运行该怎么做?可以把其中的一个程序换出到磁盘上,然后再把程序C装载到内存中。假设是把程序A换出,那么程序C还是无法装载进内存中,因为内存中空闲的连续区域有两块,一块是原来程序A占有的那10M,还有就是从0x00000080~0x00000099这20M,所以,30M的程序C无法装载进内存中。那么,唯一的办法就是把程序B换出,保留程序A,但是,此时会有60M的内存无法利用起来,很浪费对吧。

    然后,人们就去寻求一种办法来解决这些问题。
    有一句话说的好:计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。(这种思想在现在也用的很广泛,例如很多优秀的中间层:Nginx、Redis等等)
    所以,分段这种技术就出现了。为了实现分段的这个技术,需要引入虚拟地址空间的概念。那么什么是地址空间呢?简单的说就是可以寻址的一片空间。如果这个空间是虚拟的,我们就叫做虚拟地址空间;如果这个空间是真实存在的,我们就叫做物理地址空间。虚拟地址空间是可以任意的大的,因为是虚拟的。而物理地址空间是真实存在的,所以是有限的
    然后,分段这个技术做了一件什么事情呢?它把虚拟地址空间映射到了物理地址空间,并且你写的程序操作的是虚拟地址。假设,程序A的虚拟地址空间是0x00000100~0x00000200。此时,不仅需要一块连续的物理内存来存放程序A,还需要把程序A的虚拟地址空间映射到(转换为)物理地址空间。可能,程序A的虚拟地址空间从0x00000100~0x00000200映射到了物理地址空间0x00000000~0x00000100
    那么分段的技术可以解决什么问题呢?可以解决上面1、2两个问题。在问题1中,假设程序A的虚拟地址空间是0x00000000~0x00000099,映射到的物理地址空间是0x00000600~0x00000699,程序B的虚拟地址空间是0x00000100~0x00000199,映射到的物理地址空间是0x00000300~0x00000399。假设你还是手残,在程序A中操作了地址0x00000150,但是英文此时的地址0x00000150是虚拟的,而虚拟化的操作是在操作系统的掌控中的,所以,操作系统有能力判断,这个虚拟地址0x00000150是有问题的,然后阻止后续的操作。所以,体现出了隔离性。(另一种体现隔离性的方式就是,操作同一个虚拟地址,实际上可能操作的是不同的物理地址)(注意,实际上,很可能程序A和程序B的虚拟地址都是0x00000000~0x00000099。这里的举例只是为了方便理解。
    问题2也很好的解决了。正是因为这种映射,使得程序无需关注物理地址是多少,只要虚拟地址没有改变,那么,程序就不会操作地址不当。

    但是问题3仍然没有解决。因为第三个问题是换入换出的问题,这个问题的关键是能不能在换出一个完整的程序之后,把另一个完整的程序换进来。而这种分段机制,映射的是一片连续的物理内存,所以问题3得不到解决。
    而问题出在哪呢?就是完整和连续。
    而分页技术的出现就是为了解决这个问题的。分页这个技术仍然是一种虚拟地址空间到物理地址空间映射的机制。但是,粒度更加的小了。单位不是整个程序,而是某个“页”,一段虚拟地址空间组成的某一页映射到一段物理地址空间组成的某一页。(如何理解这个“页”的概念,这个问题见下面)
    分页这个技术,它的虚拟地址空间仍然是连续的,但是,每一页映射后的物理地址就不一定是连续的了。正是因为有了分页的概念,程序的换入换出就可以以页为单位了。那么,为什么就可以只换出某一页呢?实际上,不是为什么可以换出某一页,而是可以换出CPU还用不到的那些程序代码、数据。但是,把这些都换出到磁盘,万一下次CPU就要使用这些代码和数据怎么办?又得把这些代码、数据装载进内存。性能有影响对吧。所以,我们把换入换出的单位变小,变成了“页”。(实际上,这利用了空间局部性),问题3是不是就解决了呢?
    所以,分段和分页的区别在于:粒度

    分页分段的概述

    分段就是将一个程序分成代码段,数据段,堆栈段什么的
    在这里插入图片描述
    分页就是将这些段,例如代码段分成均匀的小块,然后这些给这些小块编号,然后就可以放到内存中去,由于编号了的,所以也不怕顺序乱
    在这里插入图片描述
    然后我们就能通过段号,页号,页内偏移找到程序的地址
    在这里插入图片描述

    展开全文
  • 怎样理解服务治理

    2020-07-13 23:28:37
    所以紧接着又出现了一堆让人头晕眼花的概念:服务注册发现,请求链路追踪,服务熔断,服务限流,服务管控配置,服务预警。还有就是一抓一大把的开源工具:Eurake,Zuul,Ribbon,hystrix,zipkin,dubbo,Sleuth,...

    自从微服务架构开始变得火热以后,越来越多的系统被拆解成了很多个细胞一样的微服务。设想一下,如果你的系统有100个微服务构成,要对这100个微服务进行管理,这绝对是一个不小的挑战。所以紧接着又出现了一堆让人头晕眼花的概念:服务注册发现,请求链路追踪,服务熔断,服务限流,服务管控配置,服务预警。还有就是一抓一大把的开源工具:Eurake,Zuul,Ribbon,hystrix,zipkin,dubbo,Sleuth,Elastic Search,grafna,Promethues。

    这样,当我们在说服务治理时,是不是把这些概念和工具都用上了就能够很好的治理这100多个微服务了?稍微用Google或者baidu搜索一下“服务治理”这个关键字,就很容易发现其实整个社区对服务治理都没有形成一个共识,有人理解的服务治理是基于dubbo的服务注册和服务发现,有人理解的服务治理是一整套从请求网关,服务配置中心到日志中心架构体系。
    所以这篇文章我想从现在的现象出发,分析这些概念和这些工具究竟是在解决什么问题,然后再尝试做一个简单的归纳和抽象,看看一个服务治理体系究竟应该解决哪些问题,而为了解决这些问题应该具备哪些能力。

    服务治理的那些药

    如果我们把服务治理类比成是在给一个人治病,那么上面提到的那些概念和工具,很明显就是治病的药了。既然有了这么多药了,那么不妨让我们先从这些药下手,看看这些流行的药都能是为了解决什么问题的,然后再看看这些问题之间存在什么关联。

     

    image

    让我们从Netflix全家桶开始,很多微服务架构都是基于这套全家桶的。作为一个视频流媒体行业的公司,能够自主开发并向社区贡献了这么多工具是我们应该表示感谢和敬意的。由于现在在使用这些工具的时候都是使用Spring Cloud封装好的模块,所以下面基于Spring cloud 的工具栈来进行介绍:

    • Eureka,这是一个用来注册服务的工具,通过简单的配置,在服务启动的时候就会自动注册到Eureka服务器上。
    • Hystrix,这是一个用来保护服务的熔断工具,虽然最近宣布已经停止维护更新了。
    • Zuul,这是一个用来对请求进行路由的服务网关工具,最近的zuul2采用了Netty实现了异步非阻塞编程模型。
    • Ribbon,这是一个用来分配请求的负载均衡工具
    • Feign,这是一个用来更方便调用其它服务的工具,也能进行负载均衡
    • Archaius,这是一个管理配置API的工具
    • Spring Cloud Config,用来对配置进行管理,可以把每个服务的配置放在远端服务器以方便进行配置修改
    • Spring Cloud Sleuth,Tracing采集工具包,对Zipkin,HTrace进行了封装
    • Spring Cloud Consul,封装了Consul操作,同样是用来进行服务注册发现的
    • Spring Cloud Zookeeper,封装了Zookeeper,也是用来进行服务注册发现的
    • Spring Cloud Gateway,给Spring MVC提供API网关功能的工具,里面也包含安全处理等特性

    除了Spring Cloud和Netfix提供的这些工具以外,还有下面这些工具也经常在服务监控治理中被使用:

    • Dubbo,自称是一个高性能的Java RPC框架,但是其实广泛用于服务注册发现,提供三个核心能力:面向接口的远程方法调用,智能容错和负载均衡,服务注册发现。
    • logback,java日志框架,是log4j的升级版本
    • ElasticSearch,虽然是一个搜索引擎和分析框架,但因为提供很好的存储和查询性能,所以经常用于日志的采集和存储
    • Kibana,Elastic的可视化插件,可以配合Elastic使用可视化查询日志
    • logstash,Elastic的日志分析工具
    • grafna,时序性分析工具,提供漂亮的图形化界面
    • Promethues,强大系统监控和报警框架,提供多维度数据模型,灵活强大的查询语句,有多种可视化图形界面
    • Spring boot admin,用来管理Spring Boot应用的工具,提供可视化的用户界面
    • Zipkin,分布式追踪工具,用来采集程序的延时数据
    • Htrace,Apache的分布式追踪工具。
    • resilience4j,用来被Hystrix指定作为熔断的替代工具。

    虽然这两个长长的列表已经罗列了超过20个各种工具了,但是这20多个也仅仅是整个微服务治理生态工具链中的一小部分,你肯定还知道一些我没有列出来的工具。由于这里我们的目的并不是找出所有的药,而是想分析一下这些流行的药都有什么特点,都是治什么病的。所以就先基于这些药,看看他们的共性是什么。

    如果把功能相同的进行一下归类,会发现有这样几个主要功能:

    • 服务注册发现:Eurake,Dobbo,Consul,ZooKeeper
    • 服务配置:Spring Cloud Config,Archaius
    • 服务熔断:Hystrix,resilience4j
    • 网关:Zuul,Spring Cloud Gateway
    • 负载均衡:Ribbon,Feign
    • 追踪工具:Sleuth,Zipkin,Htrace
    • 日志采集:logback,ElasticSearch
    • 监控平台:Promethues,Kibana,grafna,Spring boot admin

    这样面对这些纷繁复杂的工具我们有了一个基本的划分,当然即便是这8个分类还是有点多,而且相互之间的关系也不明确,为什么会有这8个分类的原因也不清楚。下面就一起深入一下,看看这些工具之间的内在关系究竟是什么。

    服务治理究竟要治的是什么?

    让我们先放下微服务,像《微服务设计》那本书中说的一样,把自己想象成一个城市规划师,我们的目标不是治理微服务,而是要治理一个城市的交通,那么我们会怎么思考?

     

    image

    在进行城市交通规划之前首先要做的第一个事情是收集信息,要能够知道这个城市发生了什么,所以在各个路口需要安装采集探头,记录车来车往的信息。有了信息以后就需要对信息进行分析了,那么就需要可视化的图形界面,能够一眼就看出什么地方出了问题,通往哪个工厂的路坏了。发现了问题就要解决问题了,限制一下拥堵路段的流量,把去往一个公园的车辆导向到另外一个类似的公园。最后,如果把城市作为一个国家来考虑,那么每个进入这个城市的车辆都需要进行检查,看看有没有携带违禁品,最后给这些不熟悉道路的外地车规划路线。通过上面这个思考的过程,我们发现要对一个城市进行治理的时候,第一要采集信息,然后要能够对采集的信息进行监控和分析,最后根据分析的结果采取对应的治理策略。另外从整体安全的角度考虑还需要一个守门人。

    因此我们也用同样的思路来思考服务治理,网关就是整个整体的守门人,日志采集,追踪工具,服务注册发现都是用来采集信息的,然后需要监控平台来展现这些采集的信息,并进行监控和分析。最后根据分析的结果采取治理策略,有的服务快撑不住了要限流,有的服务坏了要熔断,并且还能够及时的调整这些服务的配置。

    下面的脑图就从这四个方面构建了一个简易的服务治理体系:
    请求网关,信息采集,信息分析,治理策略

    微服务监控治理

    服务治理体系

    作为对当前服务治理领域各种纷繁复杂工具的一次简单梳理,这个体系不一定是完全准确的。但是总不能每次说到服务治理的时候我们都把几十个工具拿出来看看能用哪个工具吧。我希望达到的目的是,当大家需要对微服务进行治理和监控的时候,能够用这个简易的体系做个参考,明确的知道在请求网关,信息采集,信息分析,治理策略这四个方面还缺少了什么东西。
    当然,如果你发现除了这四个方面以外还缺少了什么东西,也非常欢迎提出来进行探讨,希望能够通过讨论得到一个更好的服务治理体系。



    作者:和坚
    链接:https://www.jianshu.com/p/dd818114ab4b
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    展开全文
  • MySql优化相关概念的理解笔记

    千次阅读 多人点赞 2018-11-27 17:43:34
    查询执行流程是怎样的: 连接 1.1客户端发起一条Query请求,监听客户端‘连接管理模块’接收请求 1.2将请求转发到‘连接进/线程模块’ 1.3调用‘用户模块’来进行授权检查 1.4通过检查后,‘连接进/线程...

    思维导图

    MySQL架构

    在这里插入图片描述

    查询执行流程

    查询执行的流程是怎样的:

    1. 连接
      1.1客户端发起一条Query请求,监听客户端的‘连接管理模块’接收请求
      1.2将请求转发到‘连接进/线程模块’
      1.3调用‘用户模块’来进行授权检查
      1.4通过检查后,‘连接进/线程模块’从‘线程连接池’中取出空闲的被缓存的连接线程和客户端请求对接,如果失败则创建一个新的连接请求。
    2. 处理
      2.1先查询缓存,检查Query语句是否完全匹配,
      2.2查询缓存失败则转交给‘命令解析器’
      2.3再转交给对应的模块处理
      2.4如果是SELECT查询还会经由‘查询优化器’做大量的优化,生成执行计划
      2.5模块收到请求后,通过‘访问控制模块’检查所连接的用户是否有访问目标表和目标字段的权限
      2.6有则调用‘表管理模块’,先是查看table cache中是否存在,有则直接对应的表和获取锁,否则重新打开表文件
      2.8根据表的meta数据,获取表的存储引擎类型等信息,通过接口调用对应的存储引擎处理
      2.9上述过程中产生数据变化的时候,若打开日志功能,则会记录到相应二进制日志文件中
    3. 结果
      3.1Query请求完成后,将结果集返回给‘连接进/线程模块’
      3.2返回的也可以是相应的状态标识,如成功或失败等
      3.3‘连接进/线程模块’进行后续的清理工作,并继续等待请求或断开与客户端的连接

    什么是优化

    • 合理安排资源、调整系统参数使MySQL运行更快、更节省资源。
    • 优化是多方面的,包括查询、表设计、服务器等。
    • 原则:减少系统瓶颈,减少资源占用,增加系统的反应速度。

    查询优化

    在优化MySQL时,通常需要库进行分析。常见的分析手段有慢查询日志EXPLAIN 分析查询,通过定位分析性能的瓶颈,才能更好的优化数据库系统的性能。

    慢查询日志

    慢查询日志开启
    在配置文件my.cnf或my.ini中在[mysqld]一行下面加入两个配置参数
    log-slow-queries=/data/mysqldata/slow-query.log
    long_query_time=5
    注:log-slow-queries参数为慢查询日志存放的位置,一般这个目录要有mysql的运行帐号的可写权限,一般都将这个目录设置为mysql的数据存放目录;
    long_query_time=5中的5表示查询超过五秒才记录;
    还可以在my.cnf或者my.ini中添加log-queries-not-using-indexes参数,表示记录下没有使用索引的查询。
    慢查询分析
    我们可以通过打开log文件查看得知哪些SQL执行效率低下
    从日志中,可以发现查询时间超过5 秒的SQL,而小于5秒的没有出现在此日志中。
    如果慢查询日志中记录内容很多,可以使用mysqldumpslow工具(MySQL客户端安装自带)来对慢查询日志进行分类汇总。mysqldumpslow对日志文件进行了分类汇总,显示汇总后摘要结果。
    进入log的存放目录,运行
    [root@mysql_data]#mysqldumpslow slow-query.log
    Reading mysql slow query log from slow-query.log
    Count: 2 Time=11.00s (22s) Lock=0.00s (0s) Rows=1.0 (2), root[root]@mysql
    select count(N) from t_user;

    mysqldumpslow命令
    /path/mysqldumpslow -s c -t 10 /database/mysql/slow-query.log
    这会输出记录次数最多的10条SQL语句,其中:

    -s, 是表示按照何种方式排序,c、t、l、r分别是按照记录次数、时间、查询时间、返回的记录数来排序,ac、at、al、ar,表示相应的倒叙
    -t, 是top n的意思,即为返回前面多少条的数据;
    -g, 后边可以写一个正则匹配模式,大小写不敏感的;

    例如:
    /path/mysqldumpslow -s r -t 10 /database/mysql/slow-log
    得到返回记录集最多的10个查询。
    /path/mysqldumpslow -s t -t 10 -g “left join” /database/mysql/slow-log
    得到按照时间排序的前10条里面含有左连接的查询语句。

    使用mysqldumpslow命令可以非常明确的得到各种我们需要的查询语句,对MySQL查询语句的监控、分析、优化是MySQL优化非常重要的一步。开启慢查询日志后,由于日志记录操作,在一定程度上会占用CPU资源影响mysql的性能,但是可以阶段性开启来定位性能瓶颈。

    EXPLAIN

    在MySQL中可以使用EXPLAIN查看SQL执行计划,用法:EXPLAIN SELECT * FROM products
    5.2.1.id
    SELECT识别符。这是SELECT查询序列号。这个不重要。
    5.2.2.select_type
    表示SELECT语句的类型。
    例如:
    1、SIMPLE
    表示简单查询,其中不包含连接查询和子查询。
    2、PRIMARY
    表示主查询,或者是最外面的查询语句。
    3、UNION
    表示连接查询的第2个或后面的查询语句。
    5.2.3.table
    表示查询的表。
    5.2.4.type
    表示表的连接类型。
    以下的连接类型的顺序是从最佳类型到最差类型:
    1、system
    表仅有一行,这是const类型的特列,平时不会出现,这个也可以忽略不计。
    2、const
    数据表最多只有一个匹配行,因为只匹配一行数据,所以很快,常用于
    3、eq_ref
    mysql手册是这样说的:“对于每个来自于前面的表的行组合,从该表中读取一行。这可能是最好的联接类型,除了const类型。它用在一个索引的所有部分被联接使用并且索引是UNIQUE或PRIMARY KEY”。eq_ref可以用于使用=比较带索引的列。
    4、ref
    查询条件索引既不是UNIQUE也不是PRIMARY KEY的情况。ref可用于=或<或>操作符的带索引的列。
    5、ref_or_null
    该联接类型如同ref,但是添加了MySQL可以专门搜索包含NULL值的行。在解决子查询中经常使用该联接类型的优化。
    上面这五种情况都是很理想的索引使用情况。
    6、index_merge
    该联接类型表示使用了索引合并优化方法。在这种情况下,key列包含了使用的索引的清单,key_len包含了使用的索引的最长的关键元素。
    7、unique_subquery
    该类型替换了下面形式的IN子查询的ref: value IN (SELECT primary_key FROM single_table WHERE some_expr)
    unique_subquery是一个索引查找函数,可以完全替换子查询,效率更高。
    8、index_subquery
    该联接类型类似于unique_subquery。可以替换IN子查询,但只适合下列形式的子查询中的非唯一索引: value IN (SELECT key_column FROM single_table WHERE some_expr)
    9、range
    只检索给定范围的行,使用一个索引来选择行。
    10、index
    该联接类型与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
    11、ALL
    对于每个来自于先前的表的行组合,进行完整的表扫描。(性能最差)
    5.2.5.possible_keys
    指出MySQL能使用哪个索引在该表中找到行。
    如果该列为NULL,说明没有使用索引,可以对该列创建索引来提高性能。
    5.2.6.key
    显示MySQL实际决定使用的键(索引)。如果没有选择索引,键是NULL。
    5.2.7.key_len
    显示MySQL决定使用的键长度。如果键是NULL,则长度为NULL。
    注意:key_len是确定了MySQL将实际使用的索引长度。
    5.2.8.ref
    显示使用哪个列或常数与key一起从表中选择行。
    5.2.9.rows
    显示MySQL认为它执行查询时必须检查的行数。
    5.2.10.Extra
    该列包含MySQL解决查询的详细信息
    Distinct:MySQL发现第1个匹配行后,停止为当前的行组合搜索更多的行。
    Not exists:MySQL能够对查询进行LEFT JOIN优化,发现1个匹配LEFT JOIN标准的行后,不再为前面的的行组合在该表内检查更多的行。
    range checked for each record (index map: #):MySQL没有发现好的可以使用的索引,但发现如果来自前面的表的列值已知,可能部分索引可以使用。
    Using filesort:MySQL需要额外的一次传递,以找出如何按排序顺序检索行。
    Using index:从只使用索引树中的信息而不需要进一步搜索读取实际的行来检索表中的列信息。
    Using temporary:为了解决查询,MySQL需要创建一个临时表来容纳结果。
    Using where:WHERE 子句用于限制哪一个行匹配下一个表或发送到客户。
    Using sort_union(…), Using union(…), Using intersect(…):这些函数说明如何为index_merge联接类型合并索引扫描。
    Using index for group-by:类似于访问表的Using index方式,Using index for group-by表示MySQL发现了一个索引,可以用来查 询GROUP BY或DISTINCT查询的所有列,而不要额外搜索硬盘访问实际的表。

    索引使用

    6.1.1.MySQL索引
    6.1.1.1.B-Tree索引
    一般来说,MySQL中的B-Tree索引的物理文件大多都是以二叉树的结构来存储的,也就是所有实际需要的数据都存放于树的叶子节点,而且到任何一个叶子节点的最短路径的长度都是完全相同的。
    6.1.1.2.R-Tree索引
    RTREE在mysql很少使用,支持该类型的存储引擎只有MyISAM、BDb、InnoDb、NDb、Archive几种。相对于BTREE,RTREE的优势在于范围查找.
    6.1.1.3.Hash索引
    Hash索引在MySQL中使用的并不是很多,目前主要是Memory存储引擎使用,而且在Memory存储引擎中将Hash索引作为默认的索引类型。所谓Hash索引,实际上就是通过一定的Hash算法,将需要索引的键值进行Hash运算,然后将得到的Hash值存入一个Hash表中。然后每次需要检索的时候,都会将检索条件进行相同算法的Hash运算,然后再和Hash表中的Hash值进行比较并得出相应的信息。
    Hash索引仅仅只能满足“=”,“IN”和“<=>”查询,不能使用范围查询;
    Hash索引无法被利用来避免数据的排序操作;
    Hash索引不能利用部分索引键查询;
    Hash索引在任何时候都不能避免表扫面;
    Hash索引遇到大量Hash值相等的情况后性能并不一定就会比B-Tree索引高;
    6.1.1.4.Full-text索引
    Full-text索引也就是我们常说的全文索引,目前在MySQL中仅有MyISAM存储引擎支持,而且也并不是所有的数据类型都支持全文索引。目前来说,仅有CHAR,VARCHAR和TEXT这三种数据类型的列可以建Full-text索引。
    6.1.2.创建索引
    是否需要创建索引,几点原则:

    • 较频繁的作为查询条件的字段应该创建索引;
    • 唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件;
    • 更新非常频繁的字段不适合创建索引;
    • 不会出现在WHERE子句中的字段不该创建索引;
      索引能够极大的提高数据检索效率,也能够改善排序分组操作的性能,但是我们不能忽略的一个问题就是索引是完全独立于基础数据之外的一部分数据,更新数据会带来的IO量和调整索引所致的计算量的资源消耗。
      6.1.3.使用索引
      6.1.3.1.使用联合索引的查询
      MySQL可以为多个字段创建索引,一个索引可以包括16个字段。对于联合索引,只有查询条件中使用了这些字段中第一个字段时,索引才会生效。
      6.1.3.2.使用OR关键字的查询
      查询语句的查询条件中只有OR关键字,且OR前后的两个条件中的列都是索引时,索引才会生效,否则,索引不生效。

    存储优化

    存储数据时,影响存储速度的主要是索引、唯一性校验、一次存储的数据条数等。

    存储数据的优化,不同的存储引擎优化手段不一样,在MySQL中常用的存储引擎有,MyISAM和InnoDB,两者的区别:

    7.1.存储引擎介绍
    7.1.1.MyISAM存储引擎
    MyISAM存储引擎是一种非事务性的引擎,提供高速存储和检索,以及全文搜索能力,适合数据仓库等查询频繁的应用。

    每一个表都被存放为三个以表名命名的物理文件。有存放表结构定义信息的.frm文件,还有存放了表的数据.MYD文件和存放索引数据的.MYI文件。

    7.1.2.Innodb 存储引擎
    Innodb 存储引擎是事务安全的, 因此如果需要一个事务安全的存储引擎,建议使用它。如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑应该使用InnoDB表。

    InnoDB 给 MySQL 提供了具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。InnoDB 提供了行锁(locking on row level),提供与 Oracle 类型一致的不加锁读取(non-locking read in SELECTs)。这些特性均提高了多用户并发操作的性能表现。

    在InnoDB表中不需要扩大锁定(lock escalation),因为 InnoDB 的列锁定(row level locks)适宜非常小的空间。InnoDB 是 MySQL 上提供外键约束(FOREIGN KEY constraints)的表引擎。

    InnoDB 的设计目标是处理大容量数据库系统,它的 CPU 利用率是其它基于磁盘的关系数据库引擎所不能比的。在技术上,InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

    InnoDB 把数据和索引存放在表空间里,可能包含多个文件,这与MyISAM不一样。InnoDB 表的大小只受限于操作系统的文件大小,一般为 2 GB。InnoDB所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件,或者是独立的表空间文件),相对来说比较不好备份。备份的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump。

    7.2.MyISAM和Innodb的区别
    InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型,这两个表类型各有优劣,视具体应用而定。基本的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。

    7.2.1.具体实现的差别:

    • MyISAM是非事务安全型的,而InnoDB是事务安全型的。
    • MyISAM锁的粒度是表级,而InnoDB支持行级锁定。
    • MyISAM支持全文类型索引,而InnoDB不支持全文索引。
    • MyISAM相对简单,所以在效率上要优于InnoDB,小型应用可以考虑使用MyISAM。
    • MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。
    • InnoDB表比MyISAM表更安全,可以在保证数据不会丢失的情况下,切换非事务表到事务表(alter table tablename type=innodb)。

    7.2.2.应用场景

    • MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。如果应用中需要执行大量的SELECT查询,那么MyISAM是更好的选择。
    • InnoDB用于事务处理应用程序,具有众多特性,包括ACID事务支持。如果应用中需要执行大量的INSERT或UPDATE操作,则应该使用InnoDB,这样可以提高多用户并发操作的性能。
      7.3.MyISAM存储优化
      7.3.1.禁用索引
      对于非空表,插入记录时,MySQL会根据表的索引对插入的记录建立索引。如果插入大量数据,建立索引会降低插入数据速度。
      为了解决这个问题,可以在批量插入数据之前禁用索引,数据插入完成后再开启索引。
      禁用索引的语句:
      ALTER TABLE table_name DISABLE KEYS
      开启索引语句:
      ALTER TABLE table_name ENABLE KEYS
      对于空表批量插入数据,则不需要进行操作,因为MyISAM引擎的表是在导入数据后才建立索引。
      7.3.2.禁用唯一性检查
      唯一性校验会降低插入记录的速度,可以在插入记录之前禁用唯一性检查,插入数据完成后再开启。
      禁用唯一性检查的语句:SET UNIQUE_CHECKS = 0;
      开启唯一性检查的语句:SET UNIQUE_CHECKS = 1;
      7.3.3.批量插入数据
      插入数据时,可以使用一条INSERT语句插入一条数据,也可以插入多条数据。
      7.3.4.使用LOAD DATA INFILE
      当需要批量导入数据时,使用LOAD DATA INFILE语句比INSERT语句插入速度快很多。
      7.4.InnoDB
      7.4.1.禁用唯一性检查
      用法和MyISAM一样。
      7.4.2.禁用外键检查
      插入数据之前执行禁止对外键的检查,数据插入完成后再恢复,可以提供插入速度。
      禁用:SET foreign_key_checks = 0;
      开启:SET foreign_key_checks = 1;
      7.4.3.禁止自动提交
      插入数据之前执行禁止事务的自动提交,数据插入完成后再恢复,可以提高插入速度。
      禁用:SET autocommit = 0;
      开启:SET autocommit = 1;

    数据库结构优化

    8.1.优化表结构

    • 尽量将表字段定义为NOT NULL约束,这时由于在MySQL中含有空值的列很难进行查询优化,NULL值会使索引以及索引的统计信息变得很复杂。
    • 对于只包含特定类型的字段,可以使用enum、set 等符合数据类型。
    • 数值型字段的比较比字符串的比较效率高得多,字段类型尽量使用最小、最简单的数据类型。例如P地址可以使用int类型。
    • 尽量使用TINYINT、SMALLINT、MEDIUM_INT作为整数类型而非INT,如果非负则加上UNSIGNED
    • VARCHAR的长度只分配真正需要的空间
    • 尽量使用TIMESTAMP而非DATETIME,
    • 单表不要有太多字段,建议在20以内
    • 合理的加入冗余字段可以提高查询速度。

    8.2.表拆分

    8.2.1.垂直拆分
    垂直拆分按照字段进行拆分,其实就是把组成一行的多个列分开放到不同的表中,这些表具有不同的结构,拆分后的表具有更少的列。例如用户表中的一些字段可能经常访问,可以把这些字段放进一张表里。另外一些不经常使用的信息就可以放进另外一张表里。

    插入的时候使用事务,也可以保证两表的数据一致。缺点也很明显,由于拆分出来的两张表存在一对一的关系,需要使用冗余字段,而且需要join操作,我们在使用的时候可以分别取两次,这样的来说既可以避免join操作,又可以提高效率。

    8.2.2.水平拆分
    水平拆分按照行进行拆分,常见的就是分库分表。以用户表为例,可以取用户ID,然后对ID取10的余数,将用户均匀的分配进这 0-9这10个表中。查找的时候也按照这种规则,又快又方便。

    有些表业务关联比较强,那么可以使用按时间划分的。例如每天的数据量很大,需要每天新建一张表。这种业务类型就是需要高速插入,但是对于查询的效率不太关心。表越大,插入数据所需要索引维护的时间也就越长。
    8.3.分区
    使用分区是大数据处理后的产物。比如系统用户的注册推广等等,会产生海量的日志,当然也可以按照时间水平拆分,建立多张表。但在实际操作中,容易发生忘记切换表导致数据错误。
    分区适用于例如日志记录,查询少。一般用于后台的数据报表分析。对于这些数据汇总需求,需要很多日志表去做数据聚合,我们能够容忍1s到2s的延迟,只要数据准确能够满足需求就可以。
    MySQL主要支持4种模式的分区:range分区、list预定义列表分区,hash 分区,key键值分区。
    8.4.读写分离
    大型网站会有大量的并发访问,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话,后果更是不堪设想。这时候,我们需要考虑如何减少数据库的联接。
    我们发现一般情况对数据库而言都是“读多写少”,也就说对数据库读取数据的压力比较大,这样分析可以采用数据库集群的方案。其中一个是主库,负责写入数据,我们称为写库;其它都是从库,负责读取数据,我们称为读库。这样可以缓解一台服务器的访问压力
    8.5.数据库集群
    如果访问量非常大,虽然使用读写分离能够缓解压力,但是一旦写操作一台服务器都不能承受了,这个时候我们就需要考虑使用多台服务器实现写操作。
    例如可以使用MyCat搭建MySql集群,对ID求3的余数,这样可以把数据分别存放到3台不同的服务器上,由MyCat负责维护集群节点的使用。

    硬件优化

    是服务器的硬件性能直接决定着MySQL数据库的性能,硬件的性能瓶颈,直接决定MySQL数据库的运行速度和效率。

    可以从以下几个方面考虑:
    1、配置较大的内存。足够大的内存,是提高MySQL数据库性能的方法之一。内存的IO比硬盘快的多,可以增加系统的缓冲区容量,使数据在内存停留的时间更长,以减少磁盘的IO。

    2、磁盘I/O相关

    • 使用SSD或者PCIe SSD设备,至少获得数百倍甚至万倍的IOPS提升;
    • 购置阵列卡同时配备CACHE及BBU模块,可明显提升IOPS
    • 尽可能选用RAID-10,而非RAID-5
    • 使用机械盘的话,尽可能选择高转速的,例如选用15000RPM,而不是7200RPM的盘
      3、配置CPU相关
         在服务器的BIOS设置中,可调整下面的几个配置:
    • 选择Performance Per Watt Optimized(DAPC)模式,发挥CPU最大性能;
    • 关闭C1E和C States等选项,提升CPU效率;
    • Memory Frequency(内存频率)选择Maximum Performance;

    MySQL缓存

    为了提高查询速度,我们可以通过不同的方式去缓存我们的结果从而提高响应效率。当我们的数据库打开了Query Cache(简称QC)功能后,数据库在执行SELECT语句时,会将其结果放到QC中,当下一次处理同样的SELECT请求时,数据库就会从QC取得结果,而不需要去数据表中查询。如果缓存命中率非常高的话,有测试表明在极端情况下可以提高效率238%。
    但一个缓存机制是否有效,效果如何,却是一个需要好好思考的问题。Query Cache有如下规则,如果数据表被更改,那么和这个数据表相关的全部Cache全部都会无效,并删除之。这里“数据表更改”包括: INSERT, UPDATE, DELETE, TRUNCATE, ALTER TABLE, DROP TABLE, or DROP DATABASE等。
    举个例子,如果数据表item访问频繁,那么意味着它的很多数据会被QC缓存起来,但是每一次item数据表的更新,无论更新是不是影响到了cache 的数据,都会将全部和item表相关的cache清除。如果你的数据表更新频繁的话,那么Query Cache将会成为系统的负担。有实验表明,糟糕时,QC会降低系统13%的处理能力。
    10.1.1.全局缓存
    数据库属于IO密集型的应用程序,其主职责就是数据的管理及存储工作。而我们知道,从内存中读取一个数据库的时间是微秒级别,而从一块普通硬盘上读取一个 IO是在毫秒级别,二者相差3个数量级。所以,要优化数据库,首先第一步需要优化的就是IO,尽可能将磁盘IO转化为内存IO,也就是使用缓存
    启动MySQL时就要分配并且总是存在的全局缓存,可以在MySQL的my.conf或者my.ini文件的[mysqld]组中配置。
    目前有:
    key_buffer_size(默认值:402653184,即384M)、
    innodb_buffer_pool_size(默认值:134217728即:128M)、innodb_additional_mem_pool_size(默认值:8388608即:8M)、innodb_log_buffer_size(默认值:8388608即:8M)、query_cache_size(默认值:33554432即:32M)等五个。总共:560M.
    10.1.1.1.key_buffer_size
    key_buffer_size是用于索引块的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),对MyISAM表性能影响最大的一个参数。如果你使它太大,系统将开始换页并且真的变慢了。
    严格说是它决定了数据库索引处理的速度,尤其是索引读的速度。对于内存在4GB左右的服务器该参数可设置为256M或384M.
    10.1.1.2.innodb_buffer_pool_size
    innodb_buffer_pool_size:主要针对InnoDB表性能影响最大的一个参数。功能与Key_buffer_size一样。InnoDB占用的内存,除innodb_buffer_pool_size用于存储页面缓存数据外,另外正常情况下还有大约8%的开销,主要用在每个缓存页帧的描述、adaptive hash等数据结构,如果不是安全关闭,启动时还要恢复的话,还要另开大约12%的内存用于恢复,两者相加就有差不多21%的开销。
    10.1.1.3.innodb_additional_mem_pool_size
    innodb_additional_mem_pool_size 设置了InnoDB存储引擎用来存放数据字典信息以及一些内部数据结构的内存空间大小,所以当我们一个MySQL Instance中的数据库对象非常多的时候,是需要适当调整该参数的大小以确保所有数据都能存放在内存中提高访问效率的。
    10.1.1.4.innodb_log_buffer_size
    innodb_log_buffer_size这是InnoDB存储引擎的事务日志所使用的缓冲区。类似于Binlog Buffer
    InnoDB在写事务日志的时候,为了提高性能,也是先将信息写入Innofb Log Buffer中,当满足innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)之后,才会将日志写到文件 (或者同步到磁盘)中。可以通过innodb_log_buffer_size 参数设置其可以使用的最大内存空间。
    InnoDB 将日志写入日志磁盘文件前的缓冲大小。理想值为 1M 至 8M。大的日志缓冲允许事务运行时不需要将日志保存入磁盘而只到事务被提交(commit)。 因此,如果有大的事务处理,设置大的日志缓冲可以减少磁盘I/O。 这个参数实际上还和另外的flush参数相关。一般来说不建议超过32MB
    10.1.1.5.query_cache_size
    query_cache_size: 主要用来缓存MySQL中的ResultSet,也就是一条SQL语句执行的结果集,所以仅仅只能针对select语句。
    当我们打开了 Query Cache功能,MySQL在接受到一条select语句的请求后,如果该语句满足Query Cache的要求,MySQL会直接根据预先设定好的HASH算法将接受到的select语句以字符串方式进行hash,然后到Query Cache中直接查找是否已经缓存。如果已经在缓存中,该select请求就会直接将数据返回,从而省略了后面所有的步骤(如SQL语句的解析,优化器优化以及向存储引擎请求数据等),极大的提高性能。
    当然,Query Cache也有一个致命的缺陷,那就是当某个表的数据有任何任何变化,都会导致所有引用了该表的select语句在Query Cache中的缓存数据失效。所以,当我们的数据变化非常频繁的情况下,使用Query Cache可能会得不偿失
    10.1.2.局部缓存
    除了全局缓冲,MySql还会为每个连接发放连接缓冲。个连接到MySQL服务器的线程都需要有自己的缓冲。大概需要立刻分配256K,甚至在线程空闲时,它们使用默认的线程堆栈,网络缓存等。事务开始之后,则需要增加更多的空间。运行较小的查询可能仅给指定的线程增加少量的内存消耗,然而如果对数据表做复杂的操作例如扫描、排序或者需要临时表,则需分配大约read_buffer_size,
    sort_buffer_size,read_rnd_buffer_size,tmp_table_size 大小的内存空间. 不过它们只是在需要的时候才分配,并且在那些操作做完之后就释放了。
    10.1.2.1.read_buffer_size
    read_buffer_size是MySql读入缓冲区大小。对表进行顺序扫描的请求将分配一个读入缓冲区,MySql会为它分配一段内存缓冲区。read_buffer_size变量控制这一缓冲区的大小。如果对表的顺序扫描请求非常频繁,并且你认为频繁扫描进行得太慢,可以通过增加该变量值以及内存缓冲区大小提高其性能.
    10.1.2.2.sort_buffer_size
    sort_buffer_size是MySql执行排序使用的缓冲大小。如果想要增加ORDER BY的速度,首先看是否可以让MySQL使用索引而不是额外的排序阶段。如果不能,可以尝试增加sort_buffer_size变量的大小
    10.1.2.3.read_rnd_buffer_size
    read_rnd_buffer_size 是MySql的随机读缓冲区大小。当按任意顺序读取行时(例如,按照排序顺序),将分配一个随机读缓存区。进行排序查询时,MySql会首先扫描一遍该缓冲,以避免磁盘搜索,提高查询速度,如果需要排序大量数据,可适当调高该值。但MySql会为每个客户连接发放该缓冲空间,所以应尽量适当设置该值,以避免内存开销过大。
    10.1.2.4.tmp_table_size
    tmp_table_size是MySql的heap (堆积)表缓冲大小。所有联合在一个DML指令内完成,并且大多数联合甚至可以不用临时表即可以完成。大多数临时表是基于内存的(HEAP)表。具有大的记录长度的临时表 (所有列的长度的和)或包含BLOB列的表存储在硬盘上。
    如果某个内部heap(堆积)表大小超过tmp_table_size,MySQL可以根据需要自动将内存中的heap表改为基于硬盘的MyISAM表。还可以通过设置tmp_table_size选项来增加临时表的大小。也就是说,如果调高该值,MySql同时将增加heap表的大小,可达到提高联接查询速度的效果。
    10.1.2.5.record_buffer:
    record_buffer每个进行一个顺序扫描的线程为其扫描的每张表分配这个大小的一个缓冲区。如果你做很多顺序扫描,你可能想要增加该值。
    10.1.3.其它缓存
    10.1.3.1.table_cache
    TABLE_CACHE(5.1.3及以后版本又名TABLE_OPEN_CACHE),table_cache指定表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问表内容。
    不能盲目地把table_cache设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。
    4.2.3.2 thread_cache_size (服务器线程缓存)
    默认的thread_cache_size=8,,这个值表示可以重新利用保存在缓存中线程的数量,当断开连接时如果缓存中还有空间,那么客户端的线程将被放到缓存中,如果线程重新被请求,那么请求将从缓存中读取,如果缓存中是空的或者是新的请求,那么这个线程将被重新创建,如果有很多新的线程,
    增加这个值可以改善系统性能.通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用。
    11.MySQL服务器参数
    通过优化MySQL的参数可以提高资源利用率,从而达到提高MySQL服务器性能的目的。MySQL的配置参数都在my.conf或者my.ini文件的[mysqld]组中,常用的参数如下:
    11.1.back_log
    back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中(每个连接256kb,占用:125M)。也就是说,如果MySql的连接数据达到max_connections时,新来的请求将会被存在堆栈中,以等待某一连接释放资源,该堆栈的数量即back_log,如果等待连接的数量超过back_log,将不被授予连接资源。
    11.2.wait_timeout
    当MySQL连接闲置超过一定时间后将会被强行关闭。MySQL默认的wait-timeout值为8个小时。
    设置这个值是非常有意义的,比如你的网站有大量的MySQL链接请求(每个MySQL连接都是要内存资源开销的),由于你的程序的原因有大量的连接请求空闲啥事也不干,白白占用内存资源,或者导致MySQL超过最大连接数从来无法新建连接导致“Too many connections”的错误。在设置之前你可以查看一下你的MYSQL的状态(可用showprocesslist),如果经常发现MYSQL中有大量的Sleep进程,则需要 修改wait-timeout值了。
    11.3.max_connections
    max_connections是指MySql的最大连接数,如果服务器的并发连接请求量比较大,建议调高此值,以增加并行连接数量,当然这建立在机器能支撑的情况下,因为如果连接数越多,介于MySql会为每个连接提供连接缓冲区,就会开销越多的内存,所以要适当调整该值,不能盲目提高设值。
    MySQL服务器允许的最大连接数16384
    11.4.max_user_connections
    max_user_connections是指每个数据库用户的最大连接针对某一个账号的所有客户端并行连接到MYSQL服务的最大并行连接数。简单说是指同一个账号能够同时连接到mysql服务的最大连接数。设置为0表示不限制。
    11.5.thread_concurrency
    thread_concurrency的值的正确与否, 对mysql的性能影响很大, 在多个cpu(或多核)的情况下,错误设置了thread_concurrency的值, 会导致mysql不能充分利用多cpu(或多核), 出现同一时刻只能一个cpu(或核)在工作的情况。thread_concurrency应设为CPU核数的2倍。
    11.6.skip-name-resolve
    skip-name-resolve:禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!
    11.7.default-storage-engine
    default-storage-engine= InnoDB(设置InnoDB类型,另外还可以设置MyISAM类型)设置创建数据库及表默认存储类型

    展开全文
  • 简介我们现代的操作系统需要防止程序崩溃导致信息丢失,需要将信息存储在文件之中。...Linux就引入了目录的概念,在Windows中可以称之为文件夹。目录的引入就会让Linux的根文件系统外观上变成了...

    简介

    我们现代的操作系统需要防止程序崩溃导致信息丢失,需要将信息存储在文件之中。而且文件能够被多个进程同时读取。在Linux中所以的资源,外设都抽象成了文件,所以就有了Linux中“一切皆文件”的特性。当然有文件,肯定是不够的,总不能把所有的文件放在一起管理,实在是太乱,不易管理维护。Linux就引入了目录的概念,在Windows中可以称之为文件夹。目录的引入就会让Linux的根文件系统外观上变成了一个层次分明的目录树。如下图:

    5917134f3bde2dd42359e675ebd85cd0.png

    目录是什么?

    在Linux中“一切皆文件”,所以这个问题很好回答:目录也是文件。目录中记录的是目录下文件名。那既然是文件,如果在创建目录的时候,与当前目录下的文件或目录重名,就肯定会创建失败。

    好了,既然搞清楚了目录的概念,我们接着往下看。

    硬链接和软连接区别?

    在Linux中表示一个文件的方式是通过两个部分来分别表示的:用户数据(user data)与元数据(meta data)。什么是用户数据呢?用户数据就是记录真实文件内容的数据,这些数据是存放在一个个大小相等的文件数据块中(data block)。

    元数据呢?其实就是这个文件的附加信息属性,例如:创建时间,文件大小等等这类信息。我们用索引号(inode)来表示每一个不同文件的元数据(当然inode也是元数据的一部分)。在Linux中,inode才是表示文件的唯一标识,而不是文件名。下图展示了怎样通过文件名来找到文件内容的。注意:元数据中并不包含文件名。文件名只是为了方便用户识别和记忆罢了。

    aeb7bd04098a7da5e8de8231b1a95c74.png

    使用什么命令可以查看inode号?

    可以使用stat和ls -i 命令查看,如下图所示:

    0503d45a0a471a7a43460681ba718275.png

    什么是硬链接?

    硬链接是指通过索引节点来进行连接。也就是存在多个文件名指向同一个inode。这样就可以将重要的文件建立硬链接,来防止“误删”的操作。

    命令:

    link oldfile newfile 

    可以创建硬链接。硬链接的inode是相同的,但是文件名不同,所以它有一些特性:

    1. 文件有相同的inode和data blocks;
    2. 不能对不存在的文件创建硬链接
    3. 不能跨文件系统创建(因为在各自文件系统下inode是唯一的,当跨文件系统就会出现inode重复的情况发生)
    4. 不能对目录创建,只能对文件进行创建
    5. 如果删除了一个硬链接文件,并不会影响其他的同inode文件(inode中存在链接计数器,删除一个硬链接相当于计数器减一,反之加一。直到为0,删除inode)
    ec18d13ba20b1d1d5b87190238eb05bb.png

    例如:

    # ls -li total 0  // 只能对已存在的文件创建硬连接 # link test.file test_hard.link link: cannot create link `test_hard.link' to `test.file': No such file or directory  # echo "This is an original file" > test.file # cat test.file This is an original file # stat test.file  File: `test.file'  Size: 25 Blocks: 8 IO Block: 4096 regular file Device: 807h/2055d Inode: 660650 Links: 2 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) ... // 文件有相同的 inode 号以及 data block # link test.file test_hard.link | ls -li total 8 660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 test_hard.link 660650 -rw-r--r-- 2 root root 25 Sep 1 17:44 test.file  // 不能交叉文件系统 # ln /dev/input/event5 /root/bfile.txt ln: failed to create test_hard link `/root/bfile.txt' => `/dev/input/event5': Invalid cross-device link  // 不能对目录进行创建硬连接 # mkdir -p test.dir/test # ln test.dir/ test_hardlink.dir ln: `test.dir/': test_hard link not allowed for directory # ls -iF 660650 test_hard.link 657948 test.dir/ 660650 test.file 

    具体的解释可以参考硬链接的5点特性。

    什么是软链接?

    软连接就和硬链接完全不同,软连接是用户数据(data blocks)中记录的是另一个文件的路径名的指向。可以理解为软连接其实就是一个普通的文件,只是他的内容非常的特殊。所以软连接有他自己的inode号以及data blocks。那我总结下软连接的特性:

    1. 软连接有自己的文件属性
    2. 可以对不存在的文件创建
    3. 软链接可以跨文件系统
    4. 软链接可以对目录创建
    5. 软链接创建不会造成链接计数器增加,因为就不是同一个inode
    6. 若链接的文件被删除了,该链接就是没有意义了,但是也可以重新创建。

    下图展示下软链接的访问过程:

    29930a2c4f69a9cee7fbe8c2ec66d1bf.png

    例如:

    # ls -li  total 0   // 可对不存在的文件创建软链接  # ln -s test.file test_soft.link  # ls -liF  total 0  789467 lrwxrwxrwx 1 root root 8 Sep 1 18:00 test_soft.link -> test.file   // 由于被指向的文件不存在,此时的软链接 test_soft.link 就是死链接  # cat test_soft.link  cat: test_soft.link: No such file or directory   // 创建被指向的文件 test.file,test_soft.link 恢复成正常的软链接  # echo "This is an original file_A" >> test.file  # cat test_soft.link  This is an original file_A   // 对不存在的目录创建软链接  # ln -s test.dir test_soft.link.dir  # mkdir -p test.dir/test  # tree . -F --inodes  . ├── [ 789497] test.dir/ │ └── [ 789498] test/ ├── [ 789495] test.file ├── [ 789495] test_soft.link -> test.file └── [ 789497] test_soft.link.dir -> test.dir/ 

    具体的解释:略

    天下数据是国内屈指可数的拥有多处海外自建机房的新型IDC服务商,被业界公认为“中国IDC行业首选品牌”。

    天下数据与全球近120多个国家顶级机房直接合作,提供包括香港、美国、韩国、日本、台湾、新加坡、荷兰、法国、英国、德国、埃及、南非、巴西、印度、越南等国家和地区的服务器、云服务器的租用服务,需要的请联系天下数据客服!

    除提供传统的IDC产品外,天下数据的主要职责是为大中型企业提供更精细、安全、满足个性需求的定制化服务器解决方案,特别是在直销、金融、视频、流媒体、游戏、电子商务、区块链、快消、物联网、大数据等诸多行业,为广大客户解决服务器租用中遇到的各种问题。

    展开全文
  • 我们该怎样理解Spring?

    2019-01-16 19:00:02
    一、spring是什么? Spring是一个开源轻量级Java SE(Java 标准版本)/Java EE(Java 企业版本)开发应用框架,其目的是用于简化企业级应用程序开发。...(1)spring可以帮我便是管理对象和他们之间依赖关...
  • 进程是什么?进程就是运行中程序,但这个概念是抽象,我们应该更深入、更...我们可以通过一个例子来理解管理含义:比如说在学校里,校长是管理者而学生是被管理者,校长是怎样管理学生呢?假如一个学生...
  • 文件系统层次结构的理解总结

    千次阅读 2016-10-18 14:21:05
    文件系统层次结构理解总结通过前面文章对文件系统逻辑结构总结,到这里再来看文件系统层次结构就... + 设备管理模块怎样理解这一个层次结构呢?带着日常使用电脑查找文件经验即可很快理解。用户接口:OS
  • 简介我们现代的操作系统需要防止程序崩溃导致信息丢失,需要将信息存储在文件之中。...Linux就引入了目录的概念,在Windows中可以称之为文件夹。目录的引入就会让Linux的根文件系统外观上变成了...
  • MySQL架构查询执行流程查询执行流程是怎样的:连接1.1客户端发起一条Query请求,监听客户端‘连接管理模块’接收请求1.2将请求转发到‘连接进/线程模块’1.3调用‘用户模块’来进行授权检查1.4通过检查后,...
  • 商业智能的概念在20世纪末被提出,是一系列以...许多企业开始使用商业智能管理系统,那么企业要怎样做才能利用好商业智能管理系统呢? 理解利益最大化的途径 对于商业智能管理系统而言,其实现利润最大化主要有...
  • MySQL架构查询执行流程查询执行流程是怎样的:连接1.1客户端发起一条Query请求,监听客户端‘连接管理模块’接收请求1.2将请求转发到‘连接进/线程模块’1.3调用‘用户模块’来进行授权检查1.4通过检查后,...
  • 前言:上一篇内存管理里面, iOS内存管理篇(一)–alloc/reatain/release/dealloc方法实现 我们提到了如何引用计数的概念,那么今天我们来看看 NSAuoreleasePool是什么,如何工作的的,又是一个怎样的原理。...
  • 研发、开发和制造的概念和关系 研发 = 研究 + 开发。 研究:未知领域。 开发:介于未知和已知之间的领域,或者说介于研究和制造之间。 制造:按照完全已知的规程把东西造出来,是完全已知的。 通过一个例子理解...
  • 进程是什么?进程就是运行中程序,但这个概念是抽象,我们应该更深入、更...我们可以通过一个例子来理解管理含义:比如说在学校里,校长是管理者而学生是被管理者,校长是怎样管理学生呢?假如一个学生...
  • 一、从概念理解运行时数据区域(作用、服务对象、可能产生问题、问题示例等) JAVA将内存分为几个数据区域,这几个区域作用各不相同。他们创建与销毁时间也不尽相同。JAVA虚拟机规范中规定几个数据...
  • 在开发过程中,不少有Spring Aop的使用,在面向切面编程时,我们会使用<...首先,我们需要明确两者的概念。 < aop:aspect>:定义切面(切面包括通知和切点) < aop:advisor>:定义通知
  • 实验要求 实验:从整理上理解进程创建、可执行文件加载和进程执行进程切换,重点理解分析fork、execve和进程...进程描述有提纲挈领作用,他可以把内存管理、文件系统、信号、进程间通信等概念和内容串起来。L...
  • 什么是jvm 我们从操作系统层面来理解,jvm其实就是操作系统中一个进程。既然是一个进程,那么我们很容易可以通过任务管理器来查看。假设此时我们启动myeclipse(myeclipse其实就是用java语言编写一个软件,...
  • 原文地址:...  Activity是Android在内存管理的优秀架构中最好的概念之一,它使得多任务能够在Android这个著名的移动操作系统完美地运行。  不管怎样,Activity不仅仅是用来加载到屏幕上的,它的
  • 一,互斥量(mutex)基本概念 互斥量是个类对象,理解成一把锁,多个线程尝试用lock()成员函数来加锁这把锁头,只有一个线程能锁定成功(成功标志是lock()函数返回) 死锁问题: 举例: 比如我有两把锁...
  • 知识管理

    2020-10-02 22:37:59
    搜索资料库中想知道相关知识,提取出来,对知识点中想要搞明白点 做专项研究(相关概念解释、自己对该概念的理解及实践) 输出 输出自己对该知识点的理解和心得体会,总结类似心得体会文章 成稿 以教为学 ...
  • 第二十章 内存等空间管理实现

    千次阅读 2015-01-25 20:16:49
    第二十章 内存等空间管理实现  空间、时间对我来说,或许永远是一个迷。即使我曾经深入到原子最深处,即使人类科学家是自欺欺人,即使我了解到最深层次部分真理是正确;那又能怎样?那都是过去式...
  • 进程、线程、资源分配、内存管理、Win32 API、服务、安全,这些是工作中常常提及但是又无法深入理解的神秘概念。在这次课程中,讲师将介绍Windows中最常见与最重要一些基本概念. 使大家能够顺利地参与到本系列之后...
  • 如果不了解虚拟机是怎样使用内存,那排查错误将会成为一项异常艰难工作。 接下来就从概念上介绍Java虚拟机内存各个区域,讲解这些区域作用、服务对象以及其中可能产生问题。 也是了解Java虚拟器内存管理...

空空如也

空空如也

1 2 3 4 5 ... 13
收藏数 241
精华内容 96
关键字:

怎样理解管理的概念