最近小小总结

mac安装了conda后,前面会有一个(base),如何取消
$ conda config --set auto_activate_base false

javaSe    

为什么能跨平台,因为先编译成class文件,再通过虚拟机来执行,所以一次编译到处运行

byte 1字节数
short 2
int 4
long 8
float 4
double 8
boolean 1
char 2

&和&&的区别(不同点):
 (1)、&逻辑运算符称为逻辑与运算符,&&逻辑运算符称为短路与运算符,也可叫逻辑与运算符。
 对于&:无论任何情况,&两边的操作数或表达式都会参与计算。
 对于&&:当&&左边的操作数为false或左边表达式结果为false时,&&右边的操作数或表达式将不参与计算,此时最终结果都为false。
 综上所述,如果逻辑与运算的第一个操作数是false或第一个表达式的结果为false时,对于第二个操作数或表达式是否进行运算,对最终的结果没有影响,结果肯定是false。推介平时多使用&&,因为它效率更高些。
、&还可以用作位运算符。当&两边操作数或两边表达式的结果不是boolean类型时,&用于按位与运算符的操作。
|和||的区别和联系与&和&&的区别和联系类似


用最有效率的方法算出2乘以8等于多少
 使用位运算来实现效率最高。位运算符是对操作数以二进制比特位为单位进行操作和运算,操作数和结果都是整型数。对于位运算符“<<”, 是将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,位运算cpu直接支持的,效率最高。所以,2乘以8等于几的最效率的方法是2 << 3。


重载 overload  在同一个类中   在一个类里一种行为提供多种实现方式并提高可读性,参数要不同

重写 override  子类与父类间    父类方法无法满足子类的要求,子类通过方法重写满足要求

this 是对象内部指代自身的引用
1.this可以调用成员变量
2.this可以调用成员方法
3.this可以在构造方法中调用重载的构造方法,且必须是构造方法的第一条语句

super代表对当前对象的直接父类对象的引用
1.super可以调用直接父类的成员变量(注意权限修饰符的影响,比如不能访问private成员)
2.super可以调用直接父类的成员方法(注意权限修饰符的影响,比如不能访问private成员)
3.super可以调用直接父类的构造方法,只限构造方法中使用,且必须是第一条语句。

abstract类是抽象类,需要被继承

final可以用来修饰类,方法和属性,不能修饰构造方法


final、finally、finalize的区别
没什么联系,final是final可以用来修饰类,方法和属性,不能修饰构造方法,finally是异常那块的,finalize是一个方法,在垃圾收集器将对象从内存中清楚出去之前做必要清理工作。


java.lang.Object类的六个常用方法

1.public boolean equals()  比较内容
2.public native hashCode()  哈希码
3.public String toString()  变成字符串
4.public final native getClass() 获取类结构信息

5.protected void finalize() throws java.lang.Throwable 垃圾回收前执行的方法
6.protected native Object clone() throws java.lang.CloneNotSupportedException 克隆

7.public final void wait() throws java.lang.InterruptedException 多线程中等待功能

8.public final native void notify() 多线程中唤醒功能

9.public final native void notifyAll() 多线程中唤醒所有等待线程的功能

权限修饰符
public > protected > defalut > private


==和equals的区别和联系


==:
    a)基本类型,比较的是值
    b)引用类型,比较的是地址
    3)不能比较没有父子关系的两个对象

    equals()
    a)系统类一般已经覆盖了equals(),比较的是内容
    b)用户自定义类如果没有覆盖equals(),将调用父类的equals(比如是Object),而Object的equals的比较是地址(return (this == obj);)
    c)用户自定义类需要覆盖父亲的equals()

注意:Object的==和equals比较的都是地址,作用相同


多态:
实现多态的三个条件
继承的存在;(继承是多态的基础,没有继承就没有多态)
子类重写父类的方法。(多态下会调用子类重写后的方法)
父类引用变量指向子类对象。(涉及子类到父类的类型转换)
向上转型 Student person = new Student()
将一个父类的引用指向一个子类对象,成为向上转型,自动进行类型转换。
此时通过父类引用变量调用的方法是子类覆盖或继承父类的方法,而不是父类的方法
此时通过父类引用变量无法调用子类特有的方法
向下转型 Student stu = (Student)person;
将一个指向子类对象的引用赋给一个子类的引用,成为向下转型,此时必须进行强制类型转换。
向下转型必须转换为父类引用指向的真实子类类型,,否则将出现ClassCastException,不是任意的强制转换
向下转型时可以结合使用instanceof运算符进行强制类型转换,比如出现转换异常。

借口跟抽象类
主要区别在于设计理念,其决定了某些情况下到底使用抽象类还是接口

抽象类体现了一种继承关系,目的是复用代码,抽象类中定义了各个子类的相同代码,可以认为父类是一个实现了部分功能的“中间产品”,而子类是“最终产品”。父类和子类之间必须存在“is-a”的关系,即父类和子类在概念本质上应该是相同的。

接口并不要求实现类和接口在概念本质上一致的,仅仅是实现了接口定义的约定或者能力而已。接口定义了“做什么”,而实现类负责完成“怎么做”,体现了功能(规范)和实现分离的原则。接口和实现之间可以认为是一种“has-a的关系”


1.Error类,表示仅靠程序本身无法恢复的严重错误,比如说内存溢出、动态链接异常、虚拟机错误。应用程序不应该抛出这种类型的对象。假如出现这种错误,除了尽力使程序安全退出外,在其他方面是无能为力的。所以在进行程序设计时,应该更关注Exception类。

2。Exception类,由Java应用程序抛出和处理的非严重错误,比如所需文件没有找到、零作除数,数组下标越界等。它的各种不同子类分别对应不同类型异常。可分为两类:Checked异常和Runtime异常


异常处理中throws和throw的区别
作用不同:throw用于程序员自行产生并抛出异常;throws用于声明在该方法内抛出了异常
使用的位置不同:throw位于方法体内部,可以作为单独语句使用;throws必须跟在方法参数列表的后面,不能单独使用。
内容不同:throw抛出一个异常对象,且只能是一个;throws后面跟异常类,而且可以有多个。

包装类:

为什么为基本类型引入包装类
基本数据类型有方便之处,简单,高效
但是java中的基本数据类型却是不面对对象的(没有属性、方法),这在实际使用时存在很多的不便(比如集合的元素只能是Obejct)


为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行包装,这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

String类为什么时final的
1.为了效率。若允许被继承,则其高度的 被使用率可能会降低程序的性能。

2.为了安全。JDK中提供的好多核心类比如String,这类的类的内部好多方法的实现都不是java编程语言本身编写的,好多方法都是调用的操作系统本地的API,这就是著名的“本地方法调用”,也只有这样才能做事,这种类是非常底层的, 和操作系统交流频繁的,那么如果这种类可以被继承的话,如果我们再把它的方法重写了,往操作系统内部写入一段具有恶意攻击性质的代码什么的, 这不就成了核心病毒了么?

3.不希望别人改,这个类就像一个工具一样,类的提供者给我们提供了, 就希望我们直接用就完了,不想让我们随便能改,其实说白了还是安全性, 如果随便能改了,那么java编写的程序肯定就很不稳定,你可以保证自己不乱改, 但是将来一个项目好多人来做,管不了别人,再说有时候万一疏忽了呢?他也不是估计的, 所以这个安全性是很重要的,java和C++相比,优点之一就包括这一点; 


String、StringBuffer、StringBuilder区别与联系
1.String类是不可变类,即一旦一个String对象被创建后,包含在这个对象中的字符序列是不可改变的,直至这个对象销毁。

2.StringBuffer类则代表一个字符序列可变的字符串,可以通过append、insert、reverse、setChartAt、setLength等方法改变其内容。一旦生成了最终的字符串,调用toString方法将其转变为String

3.JDK1.5新增了一个StringBuilder类,与StringBuffer相似,构造方法和方法基本相同。不同是StringBuffer是线程安全的,而StringBuilder是线程不安全的,所以性能略高。通常情况下,创建一个内容可变的字符串,应该优先考虑使用StringBuilder

(StringBuffer 线程安全,性能低,StringBuilder线程不安全,性能高)

String不是基本数据类型
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是 "Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个 String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。 通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为 String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。 同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做: public class Demo { private String s; ... public Demo { s = "Initial Value"; } ... } 而非 s = new String("Initial Value"); 后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。 上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。 至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即 StringBuffer。


String s = new String("xyz");创建几个String Object?
两个或一个,”xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量”xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量”xyz”对象的内容来创建出一个新String对象。如果以前就用过’xyz’,这句代表就不会创建”xyz”自己了,直接从缓冲区拿。


集合:
Collection 接口存储一组不唯一,无序的对象
List 接口存储一组不唯一,有序(插入顺序)的对象
Set接口存储一组唯一,无序的对象
Map接口存储一组键值对象,提供key到value的映射,Key无序,唯一。value不要求有序,允许重复。(如果只使用key存储,而不使用value,那就是Set)


Vector和ArrayList的区别和联系

实现原理相同,功能相同,都是长度可变的数组结构,很多情况下可以互用


两者区别就是Vector是线程安全的,ArrayList是线程不安全的, 扩容的时候Vector默认增长一倍,ArrayList增长50%


ArrayList和LinkedList的区别和联系
两者都实现了List接口,都具有List中元素有序、不唯一的特点
ArrayList实现了长度可变的数组,在内存中分配连续空间,遍历元素和随机访问元素的效率比较高 O(1),   插入、删除是O(n)


LinkedList采用链表存储方式。插入、删除元素时效率比较高        O(1)。   查询是O(n)


HashMap和Hashtable的区别和联系
实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互用
两者的主要区别如下
1.Hashtable是早期JDK提供的接口,HashMap是新版JDK提供的接口
2.Hashtable继承Dictionary类,HashMap实现Map接口
3.Hashtable线程安全,HashMap线程非安全
4.Hashtable不允许null值,HashMap允许null值


HashSet的使用和原理(hashCode()和equals()) 

1.哈希表的查询速度特别快,时间复杂度为O(1)。

2.HashMap、Hashtable、HashSet这些集合采用的是哈希表结构,需要用到hashCode哈希码,hashCode是一个整数值。

3.系统类已经覆盖了hashCode方法 自定义类如果要放入hash类集合,必须重写hashcode。如果不重写,调用的是Object的hashcode,而Object的hashCode实际上是地址。

4.向哈希表中添加数据的原理:当向集合Set中增加对象时,首先集合计算要增加对象的hashCode码,根据该值来得到一个位置用来存放当前对象,如在该位置没有一个对象存在的话,那么集合Set认为该对象在集合中不存在,直接增加进去。如果在该位置有一个对象存在的话,接着将准备增加到集合中的对象与该位置上的对象进行equals方法比较,如果该equals方法返回false,那么集合认为集合中不存在该对象,在进行一次散列,将该对象放到散列后计算出的新地址里。如果equals方法返回true,那么集合认为集合中已经存在该对象了,不会再将该对象增加到集合中了。

5.在哈希表中判断两个元素是否重复要使用到hashCode()和equals()。hashCode决定数据在表中的存储位置,而equals判断是否存在相同数据。

6. Y=K(X) :K是函数,X是哈希码,Y是地址


TreeSet的原理和使用(Comparable和comparator)
1.TreeSet中的元素不允许重复,但是有序
2.TreeSet采用树结构存储数据,存入元素时需要和树中元素进行对比,需要指定比较策略。可以通过Comparable和Comparator来指定比较策略。
3.实现了Comparable的系统类可以顺利存入TreeSet。自定义类可以实现Comparable接口来指定比较策略。
4.可创建Comparator接口实现类来指定比较策略,并通过TreeSet构造方法参数传入。这种方式尤其对系统类非常适用。


集合和数组的比较(为什么引入集合)
数组不是面向对象的,存在明显的缺陷,集合完全弥补了数组的一些缺点,比数组更灵活更实用,可大大提高软件的开发效率而且不同的集合框架类可适用于不同场合。具体如下:
1.数组的效率高于集合类
2.数组能存放基本数据类型和对象,集合类容量动态改变
3.数组容量固定且无法动态改变,集合类容量动态改变
4.数组无法判断其中实际存有多少元素,length只告诉了array的容量
5.集合有多种实现方式和不同的适用场合,而不像数组仅采用顺序表方式。
6.集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性调用即可实现各种复杂操作,大大提高软件的开发效率。


Collection和Collections的区别
Collection是Java提供的集合接口,存储一组不唯一,无序的对象。它有两个子接口List和Set。
Java中还有一个Collections类,专门用来操作集合类,它提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

1.定义:
    1.进程是具有一定独立功能的程序关于某个数据集合上的一次运动活动,是系统进行资源分配和调度的一个独立单位

    2.线程是进程的一个实体,是CPU调度和分派的基本单位,他是比进程更小的能独立运行的基本单位,线程自己基本上不拥有
    系统资源,只拥有一点在运行中必不可少的资源(如程序计数器,一组寄存器和栈),一个线程可以创建和撤销另一个线程:

2.进程和线程的关系:
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。
(4)处理机分给线程,即真正在处理机上运行的是线程。
(5)线程是指进程内的一个执行单元,也是进程内的可调度实体。
3.线程与进程的区别:
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位。
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源。
(4)系统开销:在创建或撤销进程的时候,由于系统都要为之分配和回收资源,导致系统的明显大于创建或撤销线程时的开销。但进程有独立的地址空间,进程崩溃后,在保护模式下不会对其他的进程产生影响,而线程只是一个进程中的不同的执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但是在进程切换时,耗费的资源较大,效率要差些


------------------------------------------------------------------------------------------------
zookeeper:

概念
Zookeeper 是一个分布式协调服务,可用于服务发现,分布式锁,分布式领导选举,配置管理等。 Zookeeper 提供了一个类似于 Linux 文件系统的树形结构(可认为是轻量级的内存文件系统,但 只适合存少量信息,完全不适合存储大量文件或者大文件),同时提供了对于每个节点的监控与 通知机制。


角色
Zookeeper集群是一个基于主从复制的高可用集群,每个服务器承担如下三种角色中的一种


Leader:
1.一个Zookeeper集群同一时间只会有一个实际工作的Leader,它会发起并维护与各Follower及Observer间的心跳

2.所有的写操作必须要通过Leader完成再由Leader将写操作广播给其它服务器。只要有超过半数节点(不包括observer节点)写入成功,该写请求就会被提交.


Follower
1.一个Zookeeper集群可能同时存在多个Follower,它会响应Leader的心跳
2.Follower可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理,
3.并且负责在Leader处理写请求时对请求进行投票


Observer
角色跟Follower类似,但是无投票权,Zookeeper需保证高可用和强一致性,为了支持更多的客户端,需要增加更多 Server;Server 增多,投票阶段延迟增大,影响性能;引入 Observer, Observer 不参与投票; Observers 接受客户端的连接,并将写请求转发给 leader 节点; 加入更 多 Observer 节点,提高伸缩性,同时不影响吞吐率。

zookeeper这个东西,暂时可以做一个比喻,就像大学时候的辅导员,他不上课,但是他参与你的大学生活,有啥事你也得告诉他

------------------------------------------------------------------------------------------------
Kafka
Kafka是一种高吞吐量、分布式、基于发布/订阅的消息系统,最初由LinkedIn公司开发,使用Scala语言编写,目前是Apache的开源项目

1.broker:kafka服务器,负责消息存储和转发
2.topic:消息类别,kafka按照topic来分类消息
3.partition:topic的分区,一个topic可以包含多个partition,topic消息保存在各个partition上
4.offset:消息在日志中的位置,可以理解是消息在partition上的偏移量,也是代表该消息的唯一序号
5.Producer:消息生产者
6.Consumer:消息消费者
7.Consumer Group:消费者分组,每个Consumer必须属于一个group
8.Zookeeper:保存着集群broker、topic、partition等meta数据,另外,还负责broker故障发现,partition leader选举,负载均衡等功能


kafka数据存储设计
partition的数据文件(offset,MessageSize,data)
partition中的每条message包含了以下三个属性:offset,MessageSize,data,其中offset表 示 Message 在这个 partition 中的偏移量,offset 不是该 Message 在 partition 数据文件中的实际存储位置,而是逻辑上一个值,它唯一确定了 partition 中的一条 Message,可以认为 offset 是 partition 中 Message 的 id;MessageSize 表示消息内容 data 的大小;data 为 Message 的具 体内容。


数据文件分段segment(顺序读写,分段命令、二分查找)
partition物理上由多个segment文件组成,每个segement大小相当相等,顺序读写。每个segment数据文件以该段中最小的 offset 命名,文件扩展名为.log。这样在查找指定 offset 的 Message 的 时候,用二分查找就可以定位到该 Message 在哪个 segment 数据文件中。

数据文件索引(分段索引、稀疏存储)
kafka为每个分段后的数据文件建立了索引文件,文件名与数据文件的名字是一样的,只是文件扩 展名为.index。index 文件中并没有为数据文件中的每条 Message 建立索引,而是采用了稀疏存 储的方式,每隔一定字节的数据建立一条索引。这样避免了索引文件占用过多的空间,从而可以 将索引文件保留在内存中。


生产者设计

负载均衡(partition会均衡分布到不同broker上)
由于消息 topic 由多个 partition 组成,且 partition 会均衡分布到不同 broker 上,因此,为了有 效利用 broker 集群的性能,提高消息的吞吐量,producer 可以通过随机或者 hash 等方式,将消 息平均发送到多个 partition 上,以实现负载均衡。

批量发送
是提高消息吞吐量重要的方式,Producer 端可以在内存中合并多条消息后,以一次请求的方式发 送了批量的消息给 broker,从而大大减少 broker 存储消息的 IO 操作次数。但也一定程度上影响 了消息的实时性,相当于以时延代价,换取更好的吞吐量。

ConsumerGroup
同一 Consumer Group 中的多个 Consumer 实例,不同时消费同一个 partition,等效于队列模 式。partition 内消息是有序的,Consumer 通过 pull 方式消费消息。Kafka 不删除已消费的消息
对于 partition,顺序读写磁盘数据,以时间复杂度 O(1)方式提供消息持久化能力。


------------------------------------------------------------------------------------------------
Hbase

概念

Hbase是分布式、面向列的开源数据库(其实准确的说是面向列族).HDFS为Hbase提供可靠的底层数据存储服务,MapReduce为Hbase提供高性能的计算能力,Zookeeper为Hbase提供稳定服务和Failover机制,因此我们说 Hbase 是一个通过大量廉价的机器解决海量数据的高速存 储和读取的分布式数据库解决方案。


列式存储
列方式所带来的重要好处之一就是,由于查询中的选择规则是通过列来定义的,因此整个数据库是自动索引化的。

这里的列式存储其实说的是列族存储,Hbase 是根据列族来存储数据的。列族下面可以有非常多 的列,列族在创建表的时候就必须指定。为了加深对 Hbase 列族的理解,下面是一个简单的关系 型数据库的表和 Hbase 数据库的表:


Column Family 列族
Column Family 又叫列族,Hbase 通过列族划分数据的存储,列族下面可以包含任意多的列,实 现灵活的数据存取。Hbase 表的创建的时候就必须指定列族。就像关系型数据库创建的时候必须 指定具体的列是一样的。Hbase 的列族不是越多越好,官方推荐的是列族最好小于或者等于 3。我 们使用的场景一般是 1 个列族。


Rowkey(Rowkey查询,Rowkey范围扫描,全表扫描)
Rowkey 的概念和 mysql 中的主键是完全一样的,Hbase 使用 Rowkey 来唯一的区分某一行的数 据。Hbase 只支持 3 中查询方式:基于 Rowkey 的单行查询,基于 Rowkey 的范围扫描,全表扫 描。


Region分区
 Region:Region 的概念和关系型数据库的分区或者分片差不多。Hbase 会将一个大表的数 据基于 Rowkey 的不同范围分配到不通的 Region 中,每个 Region 负责一定范围的数据访问 和存储。这样即使是一张巨大的表,由于被切割到不通的 region,访问起来的时延也很低。

TimeStamp多版本
TimeStamp 是实现 Hbase 多版本的关键。在 Hbase 中使用不同的 timestame 来标识相同 rowkey 行对应的不通版本的数据。在写入数据的时候,如果用户没有指定对应的 timestamp,Hbase 会自动添加一个 timestamp,timestamp 和服务器时间保持一致。在 Hbase 中,相同 rowkey 的数据按照 timestamp 倒序排列。默认查询的是最新的版本,用户 可同指定 timestamp 的值来读取旧版本的数据

Hbase 核心架构

Hbase 是由 Client、Zookeeper、Master、HRegionServer、HDFS 等几个组建组成。


Client:
 Client包含了访问Hbase的接口,另外Client还维护了对应的cache来加速Hbase的 访问,比如 cache 的.META.元数据的信息。

Zookeeper:
 Hbase通过Zookeeper来做master的高可用、RegionServer的监控、元数据的入口 以及集群配置的维护等工作。具体工作如下:
1. 通过 Zoopkeeper 来保证集群中只有 1 个 master 在运行,如果 master 异 常,会通过竞争机制产生新的 master 提供服务
2. 通过 Zoopkeeper 来监控 RegionServer 的状态,当 RegionSevrer 有异常的 时候,通过回调的形式通知 Master RegionServer 上下限的信息
3. 通过 Zoopkeeper 存储元数据的统一入口地址。

 Hmaster
 master节点的主要职责如下:
1. 为 RegionServer 分配 Region
2. 维护整个集群的负载均衡
3. 维护集群的元数据信息发现失效的 Region,并将失效的 Region 分配到正常
RegionServer 上当 RegionSever 失效的时候,协调对应 Hlog 的拆分


HregionServer
 HregionServer直接对接用户的读写请求,是真正的“干活”的节点。它的功能概括如 下:
1. 管理 master 为其分配的 Region
2. 处理来自客户端的读写请求
3.负责和底层 HDFS 的交互,存储数据到 HDFS 
4.负责 Region 变大以后的拆分
5.负责 Storefile 的合并工作


Region寻址方式(通过zookeeper.META)
第 1 步:Client 请求 ZK 获取.META.所在的 RegionServer 的地址。
第 2 步:Client 请求.META.所在的 RegionServer 获取访问数据所在的 RegionServer 地 址,client 会将.META.的相关信息 cache 下来,以便下一次快速访问。
第 3 步:Client 请求数据所在的 RegionServer,获取所需要的数据


HDFS
HDFS 为 Hbase 提供最终的底层数据存储服务,同时为 Hbase 提供高可用(Hlog 存储在 HDFS)的支持。

------------------------------------------------------------------------------------------------
hadoop

1.1概念

就是一个大数据解决方案。它提供了一套分布式系统基础架构。核心内容包含hdfs和mapreduce.hadoop2.0以后引入yarn

hdfs是提供数据存储的,mapreduce是方便数据计算的

1.hdfs又对应namenode和datanode。namenode 负责保存元数据的基本信息,datanode直接存放数据本身

2.mapreduce 对应jobtracker和tasktracker.jobtracker负责分发任务,tasktracker负责执行具体任务

3.对应到master/slave架构,namenode和jobtracker就应该对应到master,datanode和tasktracker就应该对应到slave


HDFS
Client(代表用户) 通过与NameNode和DataNode交互访问HDFS中的文件,Client提供了一个类似POSIX的文件系统接口供用户调用


NameNode
整个Hadoop集群中只有一个NameNode.它是整个系统的"总管",负责管理HDFS的目录树和相关的文件元数据信息。这些信息是以
"fsimage"(HDFS元数据镜像文件)和"editlog"(HDFS文件改动日志)两个文件形式存放在本地磁盘,当HDFS重启时重新构造出来的。此外,NameNode还负责监控各个DataNode的健康状况,一旦发现某个DataNode宕掉,则将该DataNode移出HDFS并重新备份其上面的数据。


Secondary NameNode
Secondary NameNode 最重要的任务并不是为NameNode元数据进行热备份,而是定期合并fsimage和edits日志.
并传输给NameNode.这里需要注意的是,为了减小NameNode压力,NameNode自己并不会合并fsimage和edits,并将文件存储到磁盘上,而是交由Secondary NameNode完成.


DataNode
一般而言,每个Slave节点上安装一个DataNode,他负责实际的数据存储,并将数据信息定期汇报给NameNode,DataNode以固定大小的block为基本单位组织文件内容,默认情况下block大小为128MB。当用户上传一个大的文件到HDFS上时,该文件会被切分成若干个block,分别存储到不同的DataNode;同时,为了保证数据可靠,会将同一个block以流水线方式写到若干个(默认是3,该参数可配置)不同的DataNode上。这种文件切割后存储的过程是对用户透明的。


MapReduce

同HDFS一样,Hadoop MapReduce也采用了Master/Slave(M/S)架构,它主要由以下几个组件组成:Client、JobTracker、TaskTracker和Task.下面分别对这几个组件进行介绍

Client

用户编写的MapReduce程序通过Client提交到JobTracker端;同时,用户可通过Client提供的一些接口查看作业运行状态。在Hadoop内部用“作业"(Job)表示MapReduce程序。一个MapReduce程序可对应若干个作业,而每个作业会被分解成若干个Map/Reduce任务(Task)

JobTracker
JobTracker主要负责资源监控和作业调度。JobTracker监控所有TaskTracker与作业的健康状况,一旦发现失败情况后,其会将相应的任务转移到其它节点;同时JobTracker会跟踪任务的执行进度,资源使用量等信息,并将这些信息告诉任务调度器,而
调度器会在资源出现空闲时,选择合适的任务使用这些资源。在Hadoop中,任务调度器时一个可插拔的模块,用户可以根据自己的需要设计相应的调度器。

TaskTracker
TaskTracker会周期性地通过Heartbeat将本节点上资源的使用情况和任务的运行进度汇报给 JobTracker, 同时接收 JobTracker 发送过来的命令并执行相应的操作(如启动新任务、 杀死任 务等)。TaskTracker 使用“slot” 等量划分本节点上的资源量。“slot” 代表计算资源(CPU、 内存等)。一个 Task 获取到一个 slot 后才有机会运行,而 Hadoop 调度器的作用就是将各个 TaskTracker 上的空闲 slot 分配给 Task 使用。 slot 分为 Map slot 和 Reduce slot 两种,分别供 MapTask 和 Reduce Task 使用。 TaskTracker 通过 slot 数目(可配置参数)限定 Task 的并发 度。

Task
Task 分为 Map Task 和 Reduce Task 两种, 均由 TaskTracker 启动。 HDFS 以固定大小的 block 为基本单位存储数据, 而对于 MapReduce 而言, 其处理单位是 split。split 与 block 的对应关 系如图所示。 split 是一个逻辑概念, 它只包含一些元数据信息, 比如数据起始位置、数据长度、 数据所在节点等。它的划分方法完全由用户自己决定。 但需要注意的是,split 的多少决定了 Map Task 的数目 ,因为每个 split 会交由一个 Map Task 处理。
Map Task 执行过程如图所示。 由该图可知,Map Task 先将对应的 split 迭代解析成一个个 key/value 对,依次调用用户自定义的 map() 函数进行处理,最终将临时结果存放到本地磁盘上, 其中临时数据被分成若干个 partition,每个 partition 将被一个 Reduce Task 处理。


Reduce Task执行过程
该过程分为三个阶段
1. 从远程节点上读取 MapTask 中间结果(称为“Shuffle 阶段”);
2. 按照 key 对 key/value 对进行排序(称为“ Sort 阶段”);
3. 依次读取<key, value list>,调用用户自定义的 reduce() 函数处理,并将最终结果存到 HDFS
上(称为“ Reduce 阶段”)。


Hadoop MapReduce 作业的生命周期

1.作业提交与初始化
1.
用户提交作业后, 首先由 JobClient 实例将作业相关信息, 比如将程序 jar 包、作业配置文 件、 分片元信息文件等上传到分布式文件系统( 一般为 HDFS)上,其中,分片元信息文件 记录了每个输入分片的逻辑位置信息。 然后 JobClient 通过 RPC 通知 JobTracker。 JobTracker 收到新作业提交请求后, 由 作业调度模块对作业进行初始化:为作业创建一个 JobInProgress 对象以跟踪作业运行状况, 而 JobInProgress 则会为每个 Task 创建一个 TaskInProgress 对象以跟踪每个任务的运行状态, TaskInProgress 可能需要管理多个 “ Task 运行尝试”( 称为“ Task Attempt”)。

2.任务调度与监控。
2.
前面提到,任务调度和监控的功能均由 JobTracker 完成。TaskTracker 周期性地通过 Heartbeat 向 JobTracker 汇报本节点的资源使用 情况, 一旦出 现空闲资源, JobTracker 会按照一定的策略选择一个合适的任务使用该空闲资源, 这由任务调度器完成。 任务调度器 是一个可插拔的独立模块, 且为双层架构, 即首先选择作业, 然后从该作业中选择任务, 其 中,选择任务时需要重点考虑数据本地性。 此外,JobTracker 跟踪作业的整个运行过程,并 为作业的成功运行提供全方位的保障。 首先, 当 TaskTracker 或者 Task 失败时, 转移计算 任务 ; 其次, 当某个 Task 执行进度远落后于同一作业的其他 Task 时,为之启动一个相同 Task, 并选取计算快的 Task 结果作为最终结果。

3.任务运行环境准备
3. 运行环境准备包括 JVM 启动和资源隔 离, 均由 TaskTracker 实现。 TaskTracker 为每个 Task 启动一个独立的 JVM 以避免不同 Task 在运行过程中相互影响 ; 同时,TaskTracker 使 用了操作系统进程实现资源隔离以防止 Task 滥用资源。

4.任务执行
4. TaskTracker 为 Task 准备好运行环境后, 便会启动 Task。 在运行过程中, 每个 Task 的最
新进度首先由 Task 通过 RPC 汇报给 TaskTracker, 再由 TaskTracker 汇报给 JobTracker。

5.作业完成。
5. 待所有 Task 执行完毕后, 整个作业执行成功。


一、什么是数据倾斜以及数据倾斜是怎么产生的?

 

简单来说数据倾斜就是数据的key 的分化严重不均,造成一部分数据很多,一部分数据很少的局面。

举个 word count 的入门例子,它的map 阶段就是形成 (“aaa”,1)的形式,然后在reduce 阶段进行 value 相加,得出 “aaa” 出现的次数。若进行 word count 的文本有100G,其中 80G 全部是 “aaa” 剩下 20G 是其余单词,那就会形成 80G 的数据量交给一个 reduce 进行相加,其余 20G 根据 key 不同分散到不同 reduce 进行相加的情况。如此就造成了数据倾斜,临床反应就是 reduce 跑到 99%然后一直在原地等着 那80G 的reduce 跑完。

 

简化了的 shuffle 图就是这样。


分组 注:group by 优于distinct group
情形:group by 维度过小,某值的数量过多
后果:处理某值的reduce非常耗时
去重 distinct count(distinct xx)
情形:某特殊值过多
后果:处理此特殊值的reduce耗时
连接 join
情形1:其中一个表较小,但是key集中
后果1:分发到某一个或几个Reduce上的数据远高于平均值
情形2:大表与大表,但是分桶的判断字段0值或空值过多
后果2:这些空值都由一个reduce处理,非常慢


三、如何处理数据倾斜问题呢?

 

1、调优参数

set hive.map.aggr=true;

set hive.groupby.skewindata=true;

 
好多同学使用这两个参数的次数真的很多,但是他们不了解这两个参数是怎么解决数据倾斜的,从哪个角度着手的。

由上面可以看出起到至关重要的作用的其实是第二个参数的设置,它使计算变成了两个mapreduce,先在第一个中在 shuffle 过程 partition 时随机给 key 打标记,使每个key 随机均匀分布到各个 reduce 上计算,但是这样只能完成部分计算,因为相同key没有分配到相同reduce上,所以需要第二次的mapreduce,这次就回归正常 shuffle,但是数据分布不均匀的问题在第一次mapreduce已经有了很大的改善,因此基本解决数据倾斜。

 
2、在 key 上面做文章,在 map 阶段将造成倾斜的key 先分成多组,例如 aaa 这个 key,map 时随机在 aaa 后面加上 1,2,3,4 这四个数字之一,把 key 先分成四组,先进行一次运算,之后再恢复 key 进行最终运算。
 

3、能先进行 group 操作的时候先进行 group 操作,把 key 先进行一次 reduce,之后再进行 count 或者 distinct count 操作。


4、join 操作中,使用 map join 在 map 端就先进行 join ,免得到reduce 时卡住。

以上4中方式,都是根据数据倾斜形成的原因进行的一些变化。要么将 reduce 端的隐患在 map 端就解决,要么就是对 key 的操作,以减缓reduce 的压力。总之了解了原因再去寻找解决之道就相对思路多了些,方法肯定不止这4种。

 

 

还有两点补充:

1. 在加个combiner函数,加上combiner相当于提前进行reduce,就会把一个mapper中的相同key进行了聚合,减少shuffle过程中数据量,以及reduce端的计算量。这种方法可以有效的缓解数据倾斜问题,但是如果导致数据倾斜的key 大量分布在不同的mapper的时候,这种方法就不是很有效了。

2. 局部聚合加全局聚合。第二种方法进行两次mapreduce,第一次在map阶段对那些导致了数据倾斜的key 加上1-n的随机前缀,这样之前相同的key 也会被分到不同的reduce中,进行聚合,这样的话就有那些倾斜的key进行局部聚合,数量就会大大降低。然后再进行第二次mapreduce这样的话就去掉随机前缀,进行全局聚合。这样就可以有效地降低mapreduce了。不过进行两次mapreduce,性能稍微比一次的差些。

 

四、总结

 

数据key分布不均的问题导致了之后一系列变化,如何使最后的结果变得有利,那就得先了解过程,然后自己引导变化使它朝有利的方向走去。


MapReduce shuffle阶段详解

在Mapreduce中,Shuffle过程是Mapreduce的核心,它分布在Mapreduce的map阶段和reduce阶段,共可分为6个详细的阶段:

1).Collect阶段:将MapTask的结果输出到默认大小为100M的MapOutputBuffer内部环形内存缓冲区,保存
的是key/value,Partition分区

2).Spilt阶段:当内存中的数据量达到一定的阀值的时候,就会将数据写入本地磁盘,在将数据写入磁盘
之前需要对数据进行一次排序的操作,先是对partition分区号进行排序,再对key排序,如果配置了
combiner,还会将有相同分区号和key的数据进行排序,如果有压缩设置,则还会对数据进行压缩操作。

3).Combiner阶段:等MapTask任务的数据处理完成之后,会对所有map产生的数据结果进行一次合并操作,
以确保一个MapTask最终只产生一个中间数据文件。

4).Copy阶段:当整个MapReduce作业的MapTask所完成的任务数据占到MapTask总数的5%时,JobTracker就会
调用ReduceTask启动,此时ReduceTask就会默认的启动5个线程到已经完成MapTask的节点上复制一份属于自
己的数据,这些数据默认会保存在内存的缓冲区中,当内存的缓冲区达到一定的阀值的时候,就会将数据写
到磁盘之上。

5).Merge阶段:在ReduceTask远程复制数据的同时,会在后台开启两个线程对内存中和本地中的数据文件进行
合并操作。

6).Sort阶段:在对数据进行合并的同时,会进行排序操作,由于MapTask阶段已经对数据进行了局部的排序,
ReduceTask只需做一次归并排序就可以保证Copy的数据的整体有效性。


mapreduce分区阶段 默认的分区方法
默认为一个分区,
如果需要多分区就自己定义个一个Partition类继承Partitioner

/** Use {@link Object#hashCode()} to partition. */
  public int getPartition(K key, V value,
                          int numReduceTasks) {
    //默认使用key的hash值与上int的最大值,避免出现数据溢出 的情况
    return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;


HDFS HA 高可用

8.1 HA概述
1)所谓HA(High Available),即高可用(7*24小时不中断服务)。
2)实现高可用最关键的策略是消除单点故障。HA严格来说应该分成各个组件的HA机制:HDFS的HA和YARN的HA。
3)Hadoop2.0之前,在HDFS集群中NameNode存在单点故障(SPOF)。
4)NameNode主要在以下两个方面影响HDFS集群: 
NameNode机器发生意外,如宕机,集群将无法使用,直到管理员重启。
NameNode机器需要升级,包括软件、硬件升级,此时集群也将无法使用。
HDFS HA功能通过配置Active/Standby两个NameNodes实现在集群中对NameNode的热备来解决上述问题。如果出现故障,如机器崩溃或机器需要升级维护,这时可通过此种方式将NameNode很快的切换到另外一台机器。
8.2 HDFS-HA工作机制
  通过双NameNode消除单点故障。

8.2.1 HDFS-HA工作要点
1、元数据管理方式需要改变
内存中各自保存一份元数据;
Edits日志只有Active状态的NameNode节点可以做写操作;
两个NameNode都可以读取Edits;
共享的Edits放在一个共享存储中管理(qjournal和NFS两个主流实现)。
2、需要一个状态管理功能模块
实现了一个zkfailover,常驻在每一个namenode所在的节点,每一个zkfailover负责监控自己所在NameNode节点,利用zk进行状态标识,当需要进行状态切换时,由zkfailover来负责切换,切换时需要防止brain split(脑裂)现象的发生。
3、必须保证两个NameNode之间能够ssh无密码登录。
4、隔离(Fence),即同一时刻仅仅有一个NameNode对外提供服务


------------------------------------------------------------------------------------------------
spark

概念
Spark 提供了一个全面、统一的框架用于管理各种有着不同性质(文本数据、图表数据等)的数据 集和数据源(批量数据或实时的流数据)的大数据处理的需求。


Spark Core
包含Spark的基本功能;尤其是定义RDD的API、操作以及这两者上的动作。其他Spark的库是构建在RDD和Spark Core之上的

Spark SQL
提供通过Apache Hive的SQL变体Hive 查询语言(HiveQL)与 Spark 进行交互的 API。每个 数据库表被当做一个 RDD,Spark SQL 查询被转换为 Spark 操作。

Spark Streaming
对实时数据流进行处理和控制。Spark Streaming 允许程序能够像普通 RDD 一样处理实时数据

Mllib
一个常用机器学习算法库,算法被实现为对 RDD 的 Spark 操作。这个库包含可扩展的学习算法, 比如分类、回归等需要对大量数据集进行迭代的操作。

Cluster Manager-制整个集群,监控 worker
在 standalone 模式中即为 Master 主节点,控制整个集群,监控 worker。在 YARN 模式中为资
源管理器
Worker 节点-负责控制计算节点 从节点,负责控制计算节点,启动 Executor 或者 Driver。
Driver: 运行 Application 的 main()函数
Executor:执行器,是为某个 Application 运行在 worker node 上的一个进程

大概编程模型
sc = new SparkContext(...)
file = sc.textFile()
file.map().flatMap().count()

Spark 应用程序从编写到提交、执行、输出的整个过程如图所示,图中描述的步骤如下:

1.用户使用SparkContext提供的API(常用的有textFile、sequenceFile、runJob、stop 等)
编写 Driver application 程序。此外 SQLContext、HiveContext 及 StreamingContext 对 SparkContext 进行封装,并提供了 SQL、Hive 及流式计算相关的 API。
2. 使用 SparkContext 提交的用户应用程序,首先会使用 BlockManager 和 BroadcastManager 将任务的 Hadoop 配置进行广播。然后由 DAGScheduler 将任务转换为 RDD 并组织成 DAG, DAG 还将被划分为不同的 Stage。最后由 TaskScheduler 借助 ActorSystem 将任务提交给 集群管理器(Cluster Manager)。
3. 集群管理器(ClusterManager)给任务分配资源,即将具体任务分配到 Worker 上,Worker 创建 Executor 来处理任务的运行。Standalone、YARN、Mesos、EC2 等都可以作为 Spark 的集群管理器。


SPARK 计算模型
RDD 可以看做是对各种数据计算模型的统一抽象,Spark 的计算过程主要是 RDD 的迭代计算过 程。RDD 的迭代计算过程非常类似于管道。分区数量取决于 partition 数量的设定,每个分区的数 据只会在一个 Task 中计算。所有分区可以在多个机器节点的 Executor 上并行执行。


1. 构建 Spark Application 的运行环境,启动 SparkContext
2. SparkContext 向资源管理器(可以是 Standalone,Mesos,Yarn)申请运行 Executor 资源,
并启动 StandaloneExecutorbackend,
3. Executor 向 SparkContext 申请 Task
4. SparkContext 将应用程序分发给 Executor
5. SparkContext 构建成 DAG 图,将 DAG 图分解成 Stage、将 Taskset 发送给 Task Scheduler, 最后由 Task Scheduler 将 Task 发送给 Executor 运行
6. Task 在 Executor 上运行,运行完释放所有资源


SPARK RDD 流程

1. 创建 RDD 对象
2. DAGScheduler 模块介入运算,计算 RDD 之间的依赖关系,RDD 之间的依赖关系就形成了
DAG
3. 每一个 Job 被分为多个 Stage。划分 Stage 的一个主要依据是当前计算因子的输入是否是确
定的,如果是则将其分在同一个 Stage,避免多个 Stage 之间的消息传递开销


SPARK RDD

(1)RDD 的创建方式
1)从 Hadoop 文件系统(或与 Hadoop 兼容的其他持久化存储系统,如 Hive、Cassandra、 HBase)输入(例如 HDFS)创建。
2)从父 RDD 转换得到新 RDD。
3)通过 parallelize 或 makeRDD 将单机数据创建为分布式 RDD。

2)RDD 的两种操作算子(转换(Transformation)与行动(Action)) 对于 RDD 可以有两种操作算子:转换(Transformation)与行动(Action)。
1) 转换(Transformation):Transformation 操作是延迟计算的,也就是说从一个 RDD 转 换生成另一个 RDD 的转换操作不是马上执行,需要等到有 Action 操作的时候才会真正触 发运算。

2)行动(Action):Action 算子会触发 Spark 提交作业(Job),并将数据输出 Spark 系统。


------------------------------------------------------------------------------------------------

Hive

数据库跟数据仓库的区别实际讲的是OLTP与OLAP的区别.

操作型处理,叫联机事务处理 OLTP(On-Line Transaction Processing,),也可以称面向交易 的处理系统,它是针对具体业务在数据库联机的日常操作,通常对少数记录进行查询、修 改。用户较为关心操作的响应时间、数据的安全性、完整性和并发支持的用户数等问题。传 统的数据库系统作为数据管理的主要手段,主要用于操作型处理。
分析型处理,叫联机分析处理 OLAP(On-Line Analytical Processing)一般针对某些主题的历 史数据进行分析,支持 管理决策。

首先要明白,数据仓库的出现,并不是要取代数据库。
数据库是面向事务的设计,数据仓库是面向主题设计的。 数据库一般存储业务数据,数据仓库存储的一般是历史数据。 数据库设计是尽量避免冗余,一般针对某一业务应用进行设计,比如一张简单的User表, 记录用户名、密码等简单数据即可,符合业务应用,但是不符合分析。数据仓库在设计 是有意引入冗余,依照分析需求,分析维度、分析指标进行设计。 数据库是为捕获数据而设计,数据仓库是为分析数据而设计。


什么是 Hive
Hive是基于Hadoop的一个数据仓库工具,可以将 结构化的数据 文件映射为一张数据库表,并 提供类SQL查询功能。
其本质是将SQL转换为MapReduce的任务进行运算,底层由HDFS来提供数据的存储,说白了 hive可以理解为一个将SQL转换为MapReduce的任务的工具,甚至更进一步可以说hive就是一 个MapReduce的客户端


为什么使用 Hive
采用类SQL语法去操作数据,提供快速开发的能力。 避免了去写MapReduce,减少开发人员的学习成本。 功能扩展很方便。

用户接口: 包括CLI、JDBC/ODBC、WebGUI。其中,CLI(command line interface)为shell命 令行;JDBC/ODBC是Hive的JAVA实现,与传统数据库JDBC类似;WebGUI是通过浏览器访 问Hive。
元数据存储: 通常是存储在关系数据库如mysql/derby中。Hive 将元数据存储在数据库 中。Hive 中的元数据包括表的名字,表的列和分区及其属性,表的属性(是否为外部表 等),表的数据所在目录等。
解释器、编译器、优化器、执行器: 完成HQL 查询语句从词法分析、语法分析、编译、优 化以及查询计划的生成。生成的查询计划存储在HDFS 中,并在随后有MapReduce 调用执 行。


2.3. Hive 与 Hadoop 的关系 Hive利用HDFS存储数据,利用MapReduce查询分析数据

2.4. Hive与传统数据库对比 hive用于海量数据的离线数据分析


external
可以让用户创建一个外部表,在建表的同时指定一个指向实际数据的路径 (LOCATION),Hive 创建内部表时,会将数据移动到数据仓库指向的路径;若创建外部 表,仅记录数据所在的路径,不对数据的位置做任何改变。(在删除表的时候,内部表的 元数据和数据会被一起删除,而外部表只删除元数据,不删除数据。)

多分区表联合查询(使用 union all )

GROUP BY 语句
GROUP BY语句通常会和聚合函数一起使用,按照一个或者多个列队结果进行分组,然后对每 个组执行聚合操作。 案例实操:
计算每个学生的平均分数

select s_id ,avg(s_score) from score group by s_id;

HAVING 语句
1. having与where不同点
1. where针对表中的列发挥作用,查询数据;having针对查询结果中的列发挥作用,筛 选数据。
2. where后面不能写分组函数,而having后面可以使用分组函数。 3. having只用于group by分组统计语句。

Order By:全局排序,一个reduce
1. 使用 ORDER BY 子句排序 ASC(ascend): 升序(默认) DESC(descend): 降序
2. ORDER BY 子句在SELECT语句的结尾。
3. 案例实操
1. 查询学生的成绩,并按照分数降序排列

SELECT * FROM student s LEFT JOIN score sco ON s.s_id = sco.s_id ORDER BY sco.s_score DESC;

每个MapReduce内部排序(Sort By)局部排序
Sort By:每个MapReduce内部进行排序,对全局结果集来说不是排序。


------------------------------------------------------------------------------------------------


Apache Impala
impala


impala 是基于 hive 的大数据分析查询引擎,直接使用 hive 的元数据库 metadata,意味着 impala 元数据都存储在 hive 的 metastore 当中,并且 impala 兼 容 hive 的绝大多数 sql 语法。所以需要安装 impala 的话,必须先安装 hive,保证 hive 安装成功,并且还需要启动 hive 的 metastore 服务。
Hive 元数据包含用 Hive 创建的 database、table 等元信息。元数据存储在关 系型数据库中,如 Derby、MySQL 等。
客户端连接 metastore 服务,metastore 再去连接 MySQL 数据库来存取元数 据。有了 metastore 服务,就可以有多个客户端同时连接,而且这些客户端不需 要知道 MySQL 数据库的用户名和密码,只需要连接 metastore 服务即可


Impala 与 Hive 异同
Impala 与 Hive 都是构建在 Hadoop 之上的数据查询工具各有不同的侧重适 应面,但从客户端使用来看 Impala 与 Hive 有很多的共同之处,如数据表元数据、 ODBC/JDBC 驱动、SQL 语法、灵活的文件格式、存储资源池等。
但是 Impala 跟 Hive 最大的优化区别在于:没有使用 MapReduce 进行并行 计算,虽然 MapReduce 是非常好的并行计算框架,但它更多的面向批处理模式, 而不是面向交互式的 SQL 执行。与 MapReduce 相比,Impala 把整个查询分成一 执行计划树,而不是一连串的 MapReduce 任务,在分发执行计划后,Impala 使 用拉式获取数据的方式获取结果,把结果数据组成按执行树流式传递汇集,减少 的了把中间结果写入磁盘的步骤,再从磁盘读取数据的开销。Impala 使用服务的 方式避免每次执行查询都需要启动的开销,即相比 Hive 没了 MapReduce 启动时 间。

3.2. 执行计划
Hive: 依赖于 MapReduce 执行框架,执行计划分成 map->shuffle->reduce->map->shuffle->reduce...的模型。如果一个 Query 会 被编 译成多轮 MapReduce,则会有更多的写中间结果。由于 MapReduce 执行框架本 身的特点,过多的中间过程会增加整个 Query 的执行时间。
Impala: 把执行计划表现为一棵完整的执行计划树,可以更自然地分发执行 计划到各个 Impalad 执行查询,而不用像 Hive 那样把它组合成管道型的 map->reduce 模式,以此保证 Impala 有更好的并发性和避免不必要的中间 sort 与 shuffle。

3.3. 数据流
Hive: 采用推的方式,每一个计算节点计算完成后将数据主动推给后续节点。
Impala: 采用拉的方式,后续节点通过 getNext 主动向前面节点要数据,以 此方式数据可以流式的返回给客户端,且只要有 1 条数据被处理完,就可以立即 展现出来,而不用等到全部处理完成,更符合 SQL 交互式查询使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值