(面试)大型网站应用之海量数据、高并发解决方案

面试时会遇到这样的提问,就记录下来,加深印象;以后工作中也可以用到。

海量数据的解决方案

网站访问数据的特点大多数呈现为”二八定律”:80%的业务访问集中在20%的数据上。例如:在某一段时间内百度的搜索热词可能集中在少部分的热门词汇上;新浪微博某一时期也可能大家广泛关注的主题也是少部分事件。

总的来说就是用户只用到了总数据条目的一小部分,当网站发展到一定规模,数据库IO操作成为性能瓶颈的时候,使用缓存将这一小部分的热门数据缓存在内存中是一个很不错的选择,不但可以减轻数据库的压力,还可以提高整体网站的数据访问速度。

使用缓存的方式可以通过程序代码将数据直接保存到内存中,例如通过使用Map或者ConcurrentHashMap;另一种,就是使用缓存框架:Redis、Ehcache、Memcache等。 使用缓存框架的时候,我们需要关心的就是什么时候创建缓存和缓存失效策略。

注意:使用缓存的时候还要考虑到缓存服务器发生故障时候如何进行容错处理,是使用N多台服务器缓存相同的数据,通过分布式部署的方式对缓存数据进行控制,当一台发生故障的时候自动切换到其他的机器上去;还是通过Hash一致性的方式,等待缓存服务器恢复正常使用的时候重新指定到该缓存服务器。Hash一致性的另一个作用就是在分布式缓存服务器下对数据进行定位,将数据分布在不用缓存服务器上。

使用传统的JSP界面,前端界面的显示是通过后台服务器进行渲染后返回给前端游览器进行解析执行。现在提倡前后端分离,前端界面基本都是HTML网页代码,通过Angular JS或者NodeJS提供的路由向后端服务器发出请求获取数据,然后在游览器对数据进行渲染,这样在很大程度上降低了后端服务器的压力。还可以将这些静态的HTML、CSS、JS、图片资源等放置在缓存服务器上或者CDN服务器上,一般使用最多的应该是CDN服务器或者Nginx服务器提供的静态资源功能。

优化前端应该遵循以下几点:

大多数网站性能的瓶颈都是开在数据库IO操作上。 对于数据库的优化来说,是一种用技术换金钱的方式。数据库优化的方式很多,常见的可以分为:

1、表结构优化

1.库名、表名、字段名必须使用小写字母,并采用下划线分割。

  • MySQL有配置参数lower_case_table_names,不可动态更改,linux系统默认为 0,即库表名以实际情况存储,大小写敏感。如果是1,以小写存储,大小写不敏感。如果是2,以实际情况存储,但以小写比较。
  • 如果大小写混合使用,可能存在abc,Abc,ABC等多个表共存,容易导致混乱。
  • 字段名显示区分大小写,但实际使⽤用不区分,即不可以建立两个名字一样但大小写不一样的字段。
  • 为了统一规范, 库名、表名、字段名使用小写字母。

2、库名、表名、字段名禁止超过32个字符

库名、表名、字段名支持最多64个字符,但为了统一规范、易于辨识以及减少传输量,禁止超过32个字符。

3、使用INNODB引擎。

INNODB引擎是MySQL5.5版本以后的默认引擘,支持事务、行级锁,有更好的数据恢复能力、更好的并发性能,同时对多核、大内存、SSD等硬件支持更好,支持数据热备份等,因此INNODB相比MyISAM有明显优势。

innodb引擎的4大特性 :

4、库名、表名、字段名禁止使用MySQL保留字。

当库名、表名、字段名等属性含有保留字时,SQL语句必须用反引号引用属性名称,这将使得SQL语句书写、SHELL脚本中变量的转义等变得⾮非常复杂。

5、禁止使用分区表。

分区表对分区键有严格要求;分区表在表变大后,执⾏行DDL、SHARDING、单表恢复等都变得更加困难。因此禁止使用分区表,并建议业务端手动SHARDING。

6.建议使用UNSIGNED存储非负数值。

同样的字节数,非负存储的数值范围更大。如TINYINT有符号为 -128-127,无符号为0-255。

7.建议使用INT UNSIGNED存储IPV4

用UNSINGED INT存储IP地址占用4字节,CHAR(15)则占用15字节。另外,计算机处理整数类型比字符串类型快。使用INT UNSIGNED而不是CHAR(15)来存储IPV4地址,通过MySQL函数inet_ntoa和inet_aton来进行转化。IPv6地址目前没有转化函数,需要使用DECIMAL或两个BIGINT来存储。

8.强烈建议使用TINYINT来代替ENUM类型。
ENUM类型在需要修改或增加枚举值时,需要在线DDL,成本较高;ENUM列值如果含有数字类型,可能会引起默认值混淆。

9.使用VARBINARY存储大小写敏感的变长字符串或二进制内容。
VARBINARY默认区分大小写,没有字符集概念,速度快。

10.INT类型固定占用4字节存储
例如INT(4)仅代表显示字符宽度为4位,不代表存储长度。数值类型括号后面的数字只是表示宽度而跟存储范围没有关系,比如INT(3)默认显示3位,空格补齐,超出时正常显示,python、java客户端等不具备这个功能。

11.区分使用DATETIME和TIMESTAMP。

存储年使用YEAR类型。存储日期使用DATE类型。 存储时间(精确到秒)建议使用TIMESTAMP类型。
DATETIME和TIMESTAMP都是精确到秒,优先选择TIMESTAMP,因为TIMESTAMP只有4个字节,而DATETIME8个字节。同时TIMESTAMP具有自动赋值以及⾃自动更新的特性。注意:在5.5和之前的版本中,如果一个表中有多个timestamp列,那么最多只能有一列能具有自动更新功能。

12.所有字段均定义为NOT NULL。

  • 对表的每一行,每个为NULL的列都需要额外的空间来标识。
  • B树索引时不会存储NULL值,所以如果索引字段可以为NULL,索引效率会下降。
  • 建议用0、特殊值或空串代替NULL值。

2、SQL优化

1、当只要一行数据时使用LIMIT 1

2、为搜索字段建索引

3、在Join表的时候使用相当类型的列,并将其索引

4、千万不要ORDER BY RAND()

5、SELECT只获取必要的字段、避免SELECT *

6、用IN代替OR。SQL语句中IN包含的值不应过多,应少于1000个。

7、SQL中避免出现now()、rand()、sysdate()、current_user()等不确定结果的函数。

8、避免使用存储过程、触发器、视图、自定义函数等。(这些高级特性有性能问题,以及未知BUG较多。业务逻辑放到数据库会造成数据库的DDL、SCALE OUT、SHARDING等变得更加困难。)

9、不要在MySQL数据库中存放业务逻辑。

3、索引优化

MySQL的优化主要分为结构优化(Scheme optimization)和查询优化(Query optimization)。

首先介绍一下联合索引。联合索引其实很简单,相对于一般索引只有一个字段,联合索引可以为多个字段创建一个索引。它的原理也很简单,比如,我们在(a,b,c)字段上创建一个联合索引,则索引记录会首先按照A字段排序,然后再按照B字段排序然后再是C字段,因此,联合索引的特点就是:

  • 第一个字段一定是有序的
  • 当第一个字段值相等的时候,第二个字段又是有序的,比如下表中当A=2时所有B的值是有序排列的,依次类推,当同一个B值得所有C字段是有序排列的、

| A | B | C |
| 1 | 2 | 3 |
| 1 | 4 | 2 |
| 1 | 1 | 4 |
| 2 | 3 | 5 |
| 2 | 4 | 4 |
| 2 | 4 | 6 |
| 2 | 5 | 5 |

其实联合索引的查找就跟查字典是一样的,先根据第一个字母查,然后再根据第二个字母查,或者只根据第一个字母查,但是不能跳过第一个字母从第二个字母开始查。这就是所谓的最左前缀原理。

我们再来详细介绍一下联合索引的查询。还是上面例子,我们在 (a,b,c)字段上建了一个联合索引,所以这个索引是先按a 再按b 再按c进行排列的,所以:

以下的查询方式都可以用到索引:

上面三个查询按照 (a ), (a,b ),(a,b,c )的顺序都可以利用到索引,这就是最左前缀匹配。

如果查询语句是:

如果查询语句是:

如果用到了最左前缀,但是顺序颠倒会用到索引码?

比如:

如果用到了最左前缀而只是颠倒了顺序,也是可以用到索引的,因为mysql查询优化器会判断纠正这条sql语句该以什么样的顺序执行效率最高,最后才生成真正的执行计划。但我们还是最好按照索引顺序来查询,这样查询优化器就不用重新编译了。

  • 最左前缀匹配原则
  • 主键外检一定要建索引
  • 对 where,on,group by,order by 中出现的列使用索引
  • 尽量选择区分度高的列作为索引,区分度的公式是count(distinct col)/count(*),表示字段不重复的比例,比例越大我们扫描的记录数越少,唯一键的区分度是1,而一些状态、性别字段可能在大数据面前区分度就是0
  • 对较小的数据列使用索引,这样会使索引文件更小,同时内存中也可以装载更多的索引键
  • 索引列不能参与计算,保持列”干净”,比如from_unixtime(create_time) = ‘2014-05-29’就不能使用到索引,原因很简单,b+树中存的都是数据表中的字段值,但进行检索时,需要把所有元素都应用函数才能比较,显然成本太大。所以语句应该写成create_time = unix_timestamp(‘2014-05-29’);
  • 为较长的字符串使用前缀索引
  • 尽量的扩展索引,不要新建索引。比如表中已经有a的索引,现在要加(a,b)的索引,那么只需要修改原来的索引即可
  • 不要过多创建索引, 权衡索引个数与DML之间关系,DML也就是插入、删除数据操作。这里需要权衡一个问题,建立索引的目的是为了提高查询效率的,但建立的索引过多,会影响插入、删除数据的速度,因为我们修改的表数据,索引也需要进行调整重建
  • 对于like查询,”%”不要放在前面。
  • 查询where条件数据类型不匹配也无法使用索引 ,字符串与数字比较不使用索引;

1、应用程序和静态资源文件进行分离

所谓的静态资源就是我们网站中用到的Html、Css、Js、Image、Video、Gif等静态资源。应用程序和静态资源文件进行分离也是常见的前后端分离的解决方案,应用服务只提供相应的数据服务,静态资源部署在指定的服务器上(Nginx服务器或者是CDN服务器上),前端界面通过Angular JS或者Node JS提供的路由技术访问应用服务器的具体服务获取相应的数据在前端游览器上进行渲染。这样可以在很大程度上减轻后端服务器的压力。例如,百度主页使用的图片就是单独的一个域名服务器上进行部署的

2、页面缓存

页面缓存是将应用生成的很少发生数据变化的页面缓存起来,这样就不需要每次都重新生成页面了,从而节省大量CPU资源,如果将缓存的页面放到内存中速度就更快。

可以使用Nginx提供的缓存功能,或者可以使用专门的页面缓存服务器Squid。

3、集群与分布式

4、反向代理

5、CDN

Original: https://www.cnblogs.com/zhuzhen/p/9340941.html
Author: 十七年蝉
Title: (面试)大型网站应用之海量数据、高并发解决方案

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/598922/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 浅谈GTID及简单测试

    今天简单介绍一下GTID,并有部分相关实验。 GTID相信大家都不陌生,GTID的英文全称为Global Transaction Identifier,在MySQL主从架构中应用广…

    数据库 2023年6月16日
    068
  • super 和 this 的区别

    一、二者的区别 1.属性的区别:this访问本类中的属性,如果本类没有此属性则从父类中继续查找。super访问父类中的属性。2.方法的区别:this访问本类中的方法,如果本类没有此…

    数据库 2023年6月11日
    084
  • 计算机中内存、cache和寄存器之间的关系及区别

    寄存器是中央处理器内的组成部份。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC)。…

    数据库 2023年6月11日
    0101
  • Java并发

    Java并发 JAVA技术交流群:737698533 CAS compare and swap 比较并交换,cas又叫做无锁,自旋锁,乐观锁,轻量级锁 例如下面的代码,如果想在多线…

    数据库 2023年6月16日
    081
  • git开发常用命令

    1.基本命令git branch 查看本地分支git branch -r 查看远程分支git checkout xxx 切换分支git pull origin master //从…

    数据库 2023年6月9日
    090
  • windows安装mysql8.0.29(ZIP解压安装版本)

    一. 下载mysql 8.0.29软件包 二. 解压,初始化安装 1,打开下载后文件所在目录,使用解压软件解压,打开文件夹!(如图,文件路径不要出现中文!) 2,创建my.ini文…

    数据库 2023年5月24日
    083
  • Hosts映射

    Hosts映射 思考:如何通过主机名能够找到(ping)某个linux系统? 前言 Hosts:是一个文本文件,用来记录IP和Hostname的映射关系 DNS:是互联网上作为域名…

    数据库 2023年6月11日
    097
  • StoneDB for MySQL 5.7 版本发布

    StoneDB_5.7_v1.0.0 的发行日志 支持MySQL 5.7 功能添加或改变 编译相关改动 配置相关改动 文档变更 BUG修复 欢迎大家关注我们的Github:http…

    数据库 2023年6月11日
    074
  • 索引的树结构

    二分查找 二叉树 二叉平衡树 B-TREE :二叉平衡树的基础上,使加载一次节点,可以加载更多路径数据,同时把查询范围缩减到更小 缺点:业务数据的大小可能远远超过了索引数据的大小,…

    数据库 2023年6月16日
    0138
  • 设计模式之(5)——原型模式

    上篇文章中我们提到单例模式可以避免重复创建消耗资源的对象,但是却不得不共用对象。若是对象本身也不让随意访问修改时,怎么办?那么我们就可以采用原型模式来创建新的实例。 定义:原型模式…

    数据库 2023年6月14日
    066
  • volatility3-windows插件

    volatility3和volatility有很大的区别 查看镜像信息,volatility会进行分析 <span class=”ne-text”>python vol…

    数据库 2023年6月11日
    087
  • Vuex 简单使用

    官网:https://vuex.vuejs.org/zh/ 参考文章:https://www.cnblogs.com/chinabin1993/p/9848720.html Vue…

    数据库 2023年6月16日
    097
  • 程序包javax.persistence不存在解决办法

    只需添加以下包即可 javax.persistence persistence-api 1.0.2 Original: https://www.cnblogs.com/javalo…

    数据库 2023年6月11日
    086
  • 【StoneDB技术解析】验证相关数据包是否需要解压缩

    在StoneDB中,数据包分为以下几类: 通过对数据包的划分,知识网格技术过滤掉不相关的数据包,读取相关的数据包和可疑的数据包。其中相关的数据包不需要解压缩,只读取元数据,不会发生…

    数据库 2023年5月24日
    075
  • 数据库多表查询 联合查询 增删改查

    插入 方式一 语法: insert into 表名 (字段名,…) values (值,…); 特点: 1、要求值的类型和字段的类型要一致或兼容 2、字段的个数和顺序不一定…

    数据库 2023年6月16日
    0149
  • 凤凰架构: 构建可靠的大型分布式系统

    推荐一本好书: 《凤凰架构: 构建可靠的大型分布式系统》–作者:周志明 这是一本开源书,同时也已经出版。有着纸质书、电子书、开源网站文档和Github文档。文末已附上链…

    数据库 2023年6月6日
    0104
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球