因为最近在准备面试,阿粉也准备了很多的面试题,因为之前很多的面试官都是从宏观到微观,也就是从基础的再到深入的,然后看你对这个技术的掌握程度如何,而阿粉遇到的这位面试官则是非常的有趣,问的问题也是很多不是在底层方面的,而是问的从大方面去如何把控,就比如阿粉的标题,海量数据。

<–more–>

1.海量数据

不的不说,这个问题肯定有大部分的人觉得没什么,不就是那么几种方式么?首先你要知道数据量达到了多少才能去使用某项技术,而这个技术还要去判断是否适合你们的项目,如果收你选择了这项技术,之后会出现很多想不到的问题,那么麻烦就会随之而来,而且会越来越多。

我们先说说什么是海量数据,因为之前阿粉也曾经当过个面试官,也面试过一些人,其中不乏有从培训机构出来的学生,因为简历不错,就被HR选中,于是就来准备面试,而它们所用的技术,和他们的数据完全匹配不上,虽然可能是学习了,但是真的知道为什么用。

海量数据,顾名思义,数据量一般大得多,之前看一个网友写的书,里面有一个非常有意思的说法,“凡是在个人计算机上处理敛据时经常出现“out of memory”提示的数据量,都可称之为海量数据”

这句话其实很有意思,就是说只要超过你们目前系统所能承受的极限,那么就是海量数据,

2.如何处理海量数据

阿粉在这里先都给提出来,然后我们一个接着一个的说。

  • 缓存,页面静态化

  • 数据库优化

  • 分离活跃数据

  • 读写分离

2.1缓存和页面静态化

在面试的时候,阿粉肯定知道大家一定会说这块的内容,因为在说数据量非常大的时候,大家一定会想到这块的内容,缓存,缓存这个东西大家也都知道,无非就是将我们从数据库中读取的数据暂时的存储起来,在下次使用的时候,不用再去数据库读取,而是通过缓存获取,这样就非常直接的降低了数据库的压力。

而我们常见的几种缓存都有哪些?

Redis,Memcache,这些都是大家能够想到的,而我们也都知道,既然你提出了这个关于缓存的概念,那么你就得知道什么时候创建缓存,以及缓存失效之后该如何处置。

但是你如果只是知道这一种,那么可能有一些较真的面试官就会给你问难题了,还有什么情况下不适合使用缓存来解决海量数据的话,你还有其他的什么方式么?这不就是要凉了的节奏。

而这缓存使用出来来解决海量数据很多是属于数据变化不大的情况,就比如说某东的商品展示,某宝的商品展示,也就是说,如果你的数据经常的变化,那么你把数据存储到缓存中的意义就不是很大了。

但是还有一个问题,那就是如果你设置的缓存是定时生效,这种情况只能是在数据要求实时性并不高的情况下进行,如果对实时性要求比较高,那么你就会出现,像之前阿粉使用抢票软件的时候,各种小黑屋,各种缓存票,所以,使用缓存的时候需要注意的就是这几点。

  1. 数据不频繁变化

  2. 实时性要求不是很高

我们再谈谈这个静态页面化,其实和缓存差不多,但是缓存主要是针对后端的数据库数据,而静态页面化主要针对的则是前端的所有内容,当我们访问项目的时候,把返回的数据在页面组装完成的时候,进行保存,保存好的数据在下次访问的时候,直接展示,不用再去数据库或者缓存中去执行,比较常用的技术也是那么几种,FreeMarker,Velocity这种都是比较常用的。

2.2数据库优化

说实话,阿粉在看到的时候,不由的又想起了之前的面试的时候,数据库SQL语句优化,数据库引擎优化,挑选合适的数据库引擎。

  1. SQL语句优化

不得不说,这个语句优化在面试里面只要你在简历上写,那么面试官百分之九十的都会提问你,常见的SQL语句优化大家都会说,比如:

  • 尽量避免非操作符的使用,在索引使用NOT ,<>,会导致索引失效,避免全表扫描

  • 避免不必要的类型转换

  • 谨慎使用模糊查询

  • 优先使用UNION ALL,避免使用UNION

诸如此类的还有很多,阿粉就不再给大家一一列出了,毕竟大家都有百度和谷歌,阿粉想给大家说的是,大家在写SQL语句的时候可以多想一点内容,比如后期哪里还会用到这个,这个在之后的代码中会不会引起其他的影响。

  1. 数据库表结构设计

数据库表结构设计有可能对初级的程序员作用不是很大,因为很多时候都是之前的老哥们帮你设计好了,你在开发中很多都是CRUD,不需要涉及到这块,但是你还是要知道,比如说:

  • 增加普通字段,减少跨表查询带来的性能消耗

  • choices参数的使用,建立外键关联一对多,自动更新字段,避免直接修改代码

数据库这个东西还是非常重要的,阿粉之前也出过很多关于SQL的文章,大家有兴趣的可以去寻找历史文章去看一下。

3.数据库分区

数据库分区是什么意思呢?

其实就是将一个表中的数据按照一定的规则分到不同的区来进行保存,这样查询数据的时候,如果数据范围在同一个区内,那么查询数据的时候就只会在这个分区内执行,这样就大幅度的提升操作的效率。

4.数据库分表

分表是为了什么呢?加入说你的一张表中的数据存放超过1000w甚至几千万往上的时候,那么你单表的操作就会非常的满,甚至满到让你无法想象,这时候我们就需要去进行分表,分表的方式其实和分区差不多。常见的几种方式,比如说:

  • 垂直切分

  • 水平切分

大家如果又兴趣的可以去找一些书去研究,去博客上看也可以,但是分区分表同样也会带来一些问题,毕竟有利有弊,学会取舍才行。

分区分表会出现哪些弊端?

  • 事务一致性

这个是比较重要的,比如说之前在很多面试的时候会问到分布式事务如何保证事务的一致性,TCC?既然都你都知道TCC了,那么肯定需要你自己手动的去学习了。

  • 跨节点分页、排序、函数问题

跨节点多库进行查询时,会出现limit分页、order by排序等问题。分页需要按照指定字段进行排序,当排序字段就是分片字段时,通过分片规则就比较容易定位到指定的分片;当排序字段非分片字段时,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。

如果说你取的数据非常多,那么分库分表的弊端就会出现了。

5.数据库索引

索引优化这块的内容相信大家肯定也都不陌生,具体的索引优化,大家可以看阿粉之前的文章,文章连接给大家:

手把手教你给 SQL 做个优化

面试官:请你说下对于一张很大的表应该如何做查询优化

2.3 分离活跃数据

虽然我们有海量的数据,但是大部分都是存储,而活跃数据却不是那么的多的话,这时候就可以采用这种方式就可以,将活跃数据单独的保存起来,把这一部分数据转移到某个表中,而在主要操作的数据表中只保存活跃用户的话,查询的时候就会默认去寻找活跃的表数据,如果找不到,那么再去保存了不活跃数据的表中去查询,这样就能提高我们查询速率了。

2.4读写分离

读写分离的本质是对数据库进行集群,这样就可以在高并发的情况下将数据库的操作分配到多个数据库服务器去处理从而降低单台服务器的压力,不过由于数据库的特殊性,每台服务器所保存的数据都需要一致,所以数据同步就成了数据库集群中最核心的问题。

如果多台服务器都可以写数据那么数据同步将变得非常复杂,所以一般情况下是将写操作交给专门的一台服务器处理,这台专门负责写的服务器叫做主服务器。当主服务器写人(增删改)数据后从底层同步到别的服务器(从服务器),读数据的时候到从服务器读取,从服务器可以有多台,这样就可以实现读写分离,并且将读请求分配到多个服务器处理。

主服务器向从服务器同步数据时,如果从服务器数量多,那么可以让主服务器先向其中一部分从服务器同步数据,第一部分从服务器接收到数据后再向另外一部分同步。

总结

其实处理海量数据的方式还有很多种,比如分布式数据库,大数据,这些都是可以的,但是如果你面试的时候对某些东西不是特别的了解,最好就说自己只是知道,但是并没有深入的研究过这个内容,不然很容易自己挖坑自己跳下去了。

文献参考

《数据处理、分析优化与商业应用》 《大型网站技术架构:核心原理与案例分析》 《July大神海量处理面试题》

Java Geek Tech wechat
欢迎订阅 Java 极客技术,这里分享关于 Java 的一切。