[spark]如何优化数据结构
2017-12-15 19:30
183 查看
导读(为什么要优化?):
在spark开发中,如果数据量很大的情况下(亿级),即使是基于内存的spark也会吃不消,很可能会发生意想不到的一些异常(堆栈溢出、OOM内存溢出等),
这时,如何优化使得我们的程序性能更加的好,速度更加的快就是第一任务了,以下是针对数据结构的一些优化解决方案供大家参考
数据结构耗费内存情况:
1、每个Java对象,都有一个对象头,会占用16个字节,主要是包括了一些对象的元信息,比如指向它的类的指针,如果一个对象本身很小,比如就包括了一个int类型的field,那么它的对象头实际上比对象自己还要大。
2、java的String对象,会比它内部的原始数据,多出40个字节,因为它内部使用的char数组来保存内部的字符序列,并且还得保存诸如数组长度之类的信息,且String使用的是UTF-16编码,所以每个字符会占用2个字节,比如,包含10个字符的String,会占用60个字节。
3、java中的集合类型,比如HashMap和LinkedList,内部使用的是链表数据结构,所以对链表中的每一个数据,都使用了Entry对象来包装,Entry对象不光有对象头,还有指向下一个Entry的指针,通常占用8个字节。
4、元素类型为原始数据类型(比如int)的集合,内部通常会使用原始数据类型的包装类型,比如Integer,来存储元素.
适用场景:
算子函数内部的局部数据,或者是算子函数外部的数据,均可参考以下数据结构的优化方案。
方案(一)
1.优先使用数组以及字符串,能不用集合类的,就不用集合类(优先使用array,而不是ArrayList、LinkedList、HashMap等集合)
示例:
比如有一个List<Integer> list = new ArrayList<Integer>(),将其替换为int[] arr = new int[]
或者说,对于HashMap、List这种数据,统一用String拼接成特殊格式的字符串,比如Map<Integer,Person> person = new HashMap<Integer,Person>()
可以优化为,特殊的字符串格式: id:name.address|id:name,address...
作用:
array既比List少了额外信息的存储开销,还能使用原始数据类型(int)来存储数据,比List中用Integer这种包装类型存储数据,要节省内存的多
方案(二)
2.应避免使用多层嵌套的对象结构,比如说;public class Teacher{private list<Student> students = new ArrayList<Student>()},这就是一个非常不好的例子,因为Teacher类的内部又嵌套了大量的小student对象
对于上述情况,也可以完全使用特殊的字符串来进行数据的存储,比如,用json字符串来存储数据,就是一个很好的选择。
示例:
{"teacherld:"1,"teacherName":"leo",students:[{"student":1,"studentName":"tom"}]}
作用:
作用同方案一
方案(三)
3.对于有些能够避免的场景:
尽量使用int替代String,因为String虽然比ArrayList、HashMap等数据结构高效、占用内存少、但是String还是有额外信息的消耗,比如之前用String表示id,那么现在完全可以用数字类型的int,来进行替代(注:id不要用常用的uuid,因为无法转成int,就用自增类型的int类型的id即可)
在spark开发中,如果数据量很大的情况下(亿级),即使是基于内存的spark也会吃不消,很可能会发生意想不到的一些异常(堆栈溢出、OOM内存溢出等),
这时,如何优化使得我们的程序性能更加的好,速度更加的快就是第一任务了,以下是针对数据结构的一些优化解决方案供大家参考
数据结构耗费内存情况:
1、每个Java对象,都有一个对象头,会占用16个字节,主要是包括了一些对象的元信息,比如指向它的类的指针,如果一个对象本身很小,比如就包括了一个int类型的field,那么它的对象头实际上比对象自己还要大。
2、java的String对象,会比它内部的原始数据,多出40个字节,因为它内部使用的char数组来保存内部的字符序列,并且还得保存诸如数组长度之类的信息,且String使用的是UTF-16编码,所以每个字符会占用2个字节,比如,包含10个字符的String,会占用60个字节。
3、java中的集合类型,比如HashMap和LinkedList,内部使用的是链表数据结构,所以对链表中的每一个数据,都使用了Entry对象来包装,Entry对象不光有对象头,还有指向下一个Entry的指针,通常占用8个字节。
4、元素类型为原始数据类型(比如int)的集合,内部通常会使用原始数据类型的包装类型,比如Integer,来存储元素.
适用场景:
算子函数内部的局部数据,或者是算子函数外部的数据,均可参考以下数据结构的优化方案。
方案(一)
1.优先使用数组以及字符串,能不用集合类的,就不用集合类(优先使用array,而不是ArrayList、LinkedList、HashMap等集合)
示例:
比如有一个List<Integer> list = new ArrayList<Integer>(),将其替换为int[] arr = new int[]
或者说,对于HashMap、List这种数据,统一用String拼接成特殊格式的字符串,比如Map<Integer,Person> person = new HashMap<Integer,Person>()
可以优化为,特殊的字符串格式: id:name.address|id:name,address...
作用:
array既比List少了额外信息的存储开销,还能使用原始数据类型(int)来存储数据,比List中用Integer这种包装类型存储数据,要节省内存的多
方案(二)
2.应避免使用多层嵌套的对象结构,比如说;public class Teacher{private list<Student> students = new ArrayList<Student>()},这就是一个非常不好的例子,因为Teacher类的内部又嵌套了大量的小student对象
对于上述情况,也可以完全使用特殊的字符串来进行数据的存储,比如,用json字符串来存储数据,就是一个很好的选择。
示例:
{"teacherld:"1,"teacherName":"leo",students:[{"student":1,"studentName":"tom"}]}
作用:
作用同方案一
方案(三)
3.对于有些能够避免的场景:
尽量使用int替代String,因为String虽然比ArrayList、HashMap等数据结构高效、占用内存少、但是String还是有额外信息的消耗,比如之前用String表示id,那么现在完全可以用数字类型的int,来进行替代(注:id不要用常用的uuid,因为无法转成int,就用自增类型的int类型的id即可)
相关文章推荐
- 算法优化,如何从120秒到0.5秒【数据结构的选择、数据类型的选择、运算优先级的选择、函数调用关系】
- Spark优化-优化数据结构
- 第117课: Spark Streaming性能优化:如何最大程度的确保Spark Cluster和Kafka链接的稳
- Spark视频王家林第119课: Spark Streaming性能优化:如何在生产环境下应对流数据峰值巨变?
- 算法优化,如何从120秒到0.5秒【数据结构的选择、数据类型的选择、运算优先级的选择、函数调用关系】
- spark优化之优化数据结构
- Spark Streaming性能优化: 如何在生成环境下应对流数据峰值巨变
- 大数据IMF传奇行动绝密课程第116课:Spark Streaming性能优化:如何在毫秒内处理大吞吐量和数据波动比较大的流计算
- 大数据IMF传奇行动绝密课程第117课:Spark Streaming性能优化:如何最大程度的确保Spark Cluster和Kafka连接的稳定性
- 第116课: Spark Streaming性能优化:如何在毫秒内处理处理大吞吐量的和数据波动比较大 的程序
- 大数据IMF传奇行动绝密课程第118课:Spark Streaming性能优化:如何获得和持续使用足够的集群计算资源
- 大数据IMF传奇行动绝密课程第119课:Spark Streaming性能优化:如何在生产环境下应对流数据峰值巨变
- Spark性能优化——优化数据结构
- 算法优化,如何从120秒到0.5秒【数据结构的选择、数据类型的选择、运算优先级的选择、函数调用关系】
- 大数据IMF传奇行动绝密课程第120课:Spark Streaming性能优化:如何在End-to-End生产环境下安全高效地把结果数据存入HBase中
- 优化SQL查询:如何写出高性能SQL语句
- Spark性能优化之道——解决Spark数据倾斜(Data Skew)的N种姿势
- VTK修炼之道12:基本数据结构_如何把几何结构&拓扑结构加入到数据集
- 在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet
- (译)如何优化cocos2d程序的内存使用和程序大小:第一部分