Ewkoll

  • 首页

  • 归档

Hadoop集群环境安装

发表于 2019-03-06 | 更新于 2019-03-14

配置服务器间免密登录

  1. 执行生成密钥命令
1
2
3
ssh-keygen -t rsa

默认生成id_rsa的私钥文件和id_rsa.pub的公钥文件。
  1. 把文件拷贝到需要免密登录的机器
1
ssh-copy-id -i id_rsa.pub root@192.168.7.252
  1. 验证是否可以免密登录
1
2
ssh root@192.168.7.252
查看authorized_keys文件,文件内部会新增对应的公钥内容
  1. The authenticity of host 192.168.0.xxx can’t be established.
1
2
修改/etc/ssh/ssh_config中的 StrictHostKeyChecking=no
这样第一次登录就不会提示。

如果需要通过ssh 登录自己的IP免密。在本机把id_rsa.pub公钥拷贝到本机的授权authorized_keys文件中去。

ZooKeeper

集群生成环境安装

Coordinating Distributed Applications with ZooKeeper 通过ZK协调分布式程序。

ZK建议的最小集群机器数量是3台,当3台机器的情况允许1台机器进入维护状态。

如果是5台机器的集群,当1台维护状态的时候,允许4台中的其中1台在发生故障不影响服务运行。

集群中的5台机器分布在同一个交换机下,如果交换机出现故障,将会导致全部发生异常。

  1. Zk需要JDK1.6以上版本。
  2. 设置Java堆大小。

端口

  1. 2181 服务端口
  2. 2888 集群内部通讯端口
  3. 3888 选举leader端口

防火墙
firewall-cmd –zone=public –permanent –add-port=2181/tcp –add-port=2888/tcp –add-port=3888/tcp
firewall-cmd –reload
firewall-cmd –list-ports
systemctl enable firewalld
systemctl start firewalld

配置文件

  1. 在conf目录下新建zoo.cfg文件内容如下:
    1
    2
    3
    4
    5
    6
    7
    8
    tickTime=2000
    initLimit=10
    syncLimit=5
    dataDir=/home/zk/data
    clientPort=2181
    server.1=master-252.com:2888:3888
    server.2=slaves-251.com:2888:3888
    server.3=slaves-229.com:2888:3888
  1. scp -r /home/zk root@master-252.com:/home/
  2. 在数据目录分别执行echo 1 > myid
  3. bin/zkServer.sh start
  4. bin/zkServer.sh stop
  5. bin/zkServer.sh status
  6. bin/zkCli.sh -server master-252.com:2181,slaves-251.com:2181,slaves-229.com:2181

Hadoop

  1. 其中一台机器作为NameNode,另外一台作为ResourceManager,其它机器DataNode和NodeManager作为Slaves。

Configuring Hadoop in Non-Secure Mode

Hadoop被2种类型配置驱动

  1. 只读配置 core-default.xml, hdfs-default.xml, yarn-default.xml and mapred-default.xml 没找到在哪。
  2. 每个节点配置 etc/hadoop/core-site.xml, etc/hadoop/hdfs-site.xml, etc/hadoop/yarn-site.xml and etc/hadoop/mapred-site.xml.
  3. 每个节点配置 etc/hadoop/hadoop-env.sh and etc/hadoop/yarn-env.sh and etc/hadoop/mapred-env.sh.

HDFS daemons are NameNode, SecondaryNameNode, and DataNode.
YARN damones are ResourceManager, NodeManager, and WebAppProxy.
If MapReduce is to be used, then the MapReduce Job History Server will also be running.
[3]配置中必须至少指定JAVA_HOME的环境变量。

NameNode HADOOP_NAMENODE_OPTS
DataNode HADOOP_DATANODE_OPTS
Secondary NameNode HADOOP_SECONDARYNAMENODE_OPTS
ResourceManager YARN_RESOURCEMANAGER_OPTS
NodeManager YARN_NODEMANAGER_OPTS
WebAppProxy YARN_PROXYSERVER_OPTS
Map Reduce Job History Server HADOOP_JOB_HISTORYSERVER_OPTS
Daemons Process Id Files HADOOP_PID_DIR
HDaemons Logs Files Path HADOOP_LOG_DIR

配置
grep -ri hadoop_deprecate_envvar

启动Hadoop

  1. 先格式化分布式文件系统。
    $HADOOP_PREFIX/bin/hdfs namenode -format <cluster_name>

  2. 启动名称节点
    $HADOOP_PREFIX/sbin/hadoop-daemon.sh –script hdfs start namenode

  3. 启动数据节点
    $HADOOP_PREFIX/sbin/hadoop-daemon.sh –script hdfs start datanode

  4. 启动HDFS合并2和3操作。
    $HADOOP_PREFIX/sbin/start-dfs.sh

  5. 停止HDFS。
    $HADOOP_PREFIX/sbin/stop-dfs.sh

  6. 打开8088-65535的所有端口
    firewall-cmd –zone=public –permanent –add-port=8088-65535/tcp
    firewall-cmd –zone=public –permanent –add-port=8030-8033/tcp
    firewall-cmd –zone=public –permanent –add-port=8040/tcp
    firewall-cmd –zone=public –permanent –add-port=8042/tcp
    firewall-cmd –zone=public –permanent –add-port=8045-8048/tcp

  7. 启动资源管理节点
    $HADOOP_YARN_HOME/sbin/yarn-daemon.sh start resourcemanager

  8. 启动节点管理
    $HADOOP_YARN_HOME/sbin/yarn-daemons.sh start nodemanager

  9. 启动代理服务器
    $HADOOP_YARN_HOME/sbin/yarn-daemon.sh start proxyserver

  10. 启动yarn
    $HADOOP_PREFIX/sbin/start-yarn.sh

  11. Start the MapReduce JobHistory Server
    $HADOOP_PREFIX/sbin/mr-jobhistory-daemon.sh start historyserver

  12. 获取RM中节点激活状态
    yarn rmadmin -getServiceState rm1

  13. 转移激活状态
    yarn rmadmin -transitionToActive rm1

Hadoop 集群配置
Hadoop Yarn HA 配置
Hadoop Hdfs HA 配置

Htop安装

发表于 2019-03-06

安装Htop

1
2
yum -y install epel-release
yum -y install htop

Java字节码(.class文件结构)

发表于 2018-12-20

简单记录.Class文件结构

ClassFile总体结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
  1. magic

    标识是否是class文件,正常class文件开头都是4个字节0xCAFEBABE.

  2. minor_version major_version

    编译成class文件的版本号,java6编译的major_version是0x32.

  3. constant_pool_count

    常量池的数量。

  4. constant_pool

    常量池,用于存放不同类型的数据,各种字符串,变量名称,变量类型都会存储在常量池。

    1
    2
    3
    4
    cp_info {
    u1 tag;
    u1 info[];
    }

    | Constant Type | Value |
    | —————————– | —– |
    | CONSTANT_Class | 7 |
    | CONSTANT_Fieldref | 9 |
    | CONSTANT_Methodref | 10 |
    | CONSTANT_InterfaceMethodref | 11 |
    | CONSTANT_String | 8 |
    | CONSTANT_Integer | 3 |
    | CONSTANT_Float | 4 |
    | CONSTANT_Long | 5 |
    | CONSTANT_Double | 6 |
    | CONSTANT_NameAndType | 12 |
    | CONSTANT_Utf8 | 1 |
    | CONSTANT_MethodHandle | 15 |
    | CONSTANT_MethodType | 16 |
    | CONSTANT_InvokeDynamic | 18 |

  5. access_flags

    指定接口和类的访问权限。

    | Flag Name | Value | Interpretation |
    | ————- | ———-| —————————————————–|
    | ACC_PUBLIC | 0x0001 | 公共,可以被外部包访问。 |
    | ACC_FINAL | 0x0010 | 不允许继承. |
    | ACC_SUPER | 0x0020 | 当被invoke.指令调用时,要特别对待超类方法。 |
    | ACC_INTERFACE | 0x0200 | 接口类。 |
    | ACC_ABSTRACT | 0x0400 | 抽象类,不能实例化。 |
    | ACC_SYNTHETIC | 0x1000 | 编译器生成,不在源代码中。 |
    | ACC_ANNOTATION| 0x2000 | 注解类型。 |
    | ACC_ENUM | 0x4000 | 枚举类型。 |

  6. this_class

    指向的是在静态区的CONSTANT_class_info结构体,说明当前的类名称。

  7. super_class

    0 或者 指向的是在静态区的CONSTANT_class_info结构体,说明当前的父类名称。

  8. interfaces_count

    说明接口的数量

  9. interfaces

    指向CONSTANT_class_info数组,记录当前类的实现接口。

  10. fields_count

    字段数量

  11. fields

    字段信息。

    1
    2
    3
    4
    5
    6
    7
    field_info {
    u2 access_flags;
    u2 name_index;
    u2 descriptor_index;
    u2 attributes_count;
    attribute_info attributes[attributes_count];
    }

    | Flag Name | Value | Interpretation |
    | ————- | ——— | —————————————— |
    | ACC_PUBLIC | 0x0001 | pubilc,包外可访问。 |
    | ACC_PRIVATE | 0x0002 | private,只可在类内访问。 |
    | ACC_PROTECTED | 0x0004 | protected,类内和子类中可访问。 |
    | ACC_STATIC | 0x0008 | static. 静态。 |
    | ACC_FINAL | 0x0010 | final. 常量。 |
    | ACC_VOLATILE | 0x0040 | 易变类型。 |
    | ACC_TRANSIENT | 0x0080 | 序列化忽略。 |
    | ACC_SYNTHETIC | 0x1000 | 编译器产生。 |
    | ACC_ENUM | 0x4000 | 枚举类型。 |

  12. methods_count

    方法数量

  13. methods

    方法信息。

    1
    2
    3
    4
    5
    6
    7
    method_info {
    u2 access_flags;
    u2 name_index;
    u2 descriptor_index;
    u2 attributes_count;
    attribute_info attributes[attributes_count];
    }

    | Flag Name | Value | Interpretation |
    | - | - | - |
    | ACC_PUBLIC | 0x0001 | 公共方法
    | ACC_PRIVATE | 0x0002 | 私有方法
    | ACC_PROTECTED | 0x0004 | 保护方法
    | ACC_STATIC | 0x0008 | 静态方法
    | ACC_FINAL | 0x0010 | 不允许重写
    | ACC_SYNCHRONIZED | 0x0020 | Declared synchronized; invocation is wrapped by a monitor use.
    | ACC_BRIDGE | 0x0040 | 编译器生成
    | ACC_VARARGS | 0x0080 | 可变参数
    | ACC_NATIVE | 0x0100 | Native方法
    | ACC_ABSTRACT | 0x0400 | 抽象方法
    | ACC_STRICT | 0x0800 | 浮点数模型2.8.2
    | ACC_SYNTHETIC | 0x1000 | 编译器生成方法

  14. attributes_count

    属性数量

  15. attributes

    属性信息

静态区结构体

  1. CONSTANT_Class_info 代表接口或者类

    1
    2
    3
    4
    CONSTANT_Class_info {
    u1 tag; // 7
    u2 name_index; // 指向静态区的CONSTANT_Utf8_info存储名称。
    }
  2. CONSTANT_Fieldref_info 用于记录字段信息

    1
    2
    3
    4
    5
    CONSTANT_Fieldref_info {
    u1 tag; // 9
    u2 class_index; // 指向的可能是classtype或者interfacetype
    u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
    }
  3. CONSTANT_Methodref_info 用于记录方法信息

    1
    2
    3
    4
    5
    CONSTANT_Methodref_info {
    u1 tag; // 10
    u2 class_index; // classtype
    u2 name_and_type_index; // 如果是<开始的,那么一定是void <init>的方法
    }
  4. CONSTANT_InterfaceMethodref_info 用于记录接口中的方法信息

    1
    2
    3
    4
    5
    CONSTANT_InterfaceMethodref_info {
    u1 tag; // 11
    u2 class_index; // interfacetype
    u2 name_and_type_index; // 指向 CONSTANT_NameAndType_info 字段描述或者方法描述
    }
  5. CONSTANT_String_info 记录字符串。

    1
    2
    3
    4
    CONSTANT_String_info {
    u1 tag; // 8
    u2 string_index; // 指向CONSTANT_Utf8_info
    }
  6. CONSTANT_Integer_info 记录Int类型常量

    1
    2
    3
    4
    CONSTANT_Integer_info {
    u1 tag; // 3
    u4 bytes; // 整型常量
    }
  7. CONSTANT_Float_info 记录浮点数常量

    1
    2
    3
    4
    CONSTANT_Float_info {
    u1 tag; // 4
    u4 bytes; // 浮点常量
    }

    几个特殊值:

    0x7f800000 => Float.POSITIVE_INFINITY

    0xff800000 => Float.NEGATIVE_INFINITY

    0x7f800001 to 0x7fffffff => Float.NaN

    0xff800001 to 0xffffffff => Float.NaN

    1. CONSTANT_Long_info 记录long类型常量

      1
      2
      3
      4
      5
      CONSTANT_Long_info {
      u1 tag; // 5
      u4 high_bytes; // 高4位
      u4 low_bytes; // 低4位
      }
  8. CONSTANT_Double_info 记录Double类型常量

    1
    2
    3
    4
    5
    CONSTANT_Double_info {
    u1 tag; // 6
    u4 high_bytes; // 双精度浮点的高四位值
    u4 low_bytes; // 双精度浮点的低四位值
    }

    几个特殊值:

    0x7ff0000000000000L => Double.POSITIVE_INFINITY

    0xfff0000000000000L => Double.NEGATIVE_INFINITY

    0x7ff0000000000001L to 0x7fffffffffffffffL => Double.NaN

    0xfff0000000000001L to 0xffffffffffffffffL => Double.NaN

  9. CONSTANT_NameAndType_info 记录方法或字段的名称(name)和描述符(descriptor)

    1
    2
    3
    4
    5
    CONSTANT_NameAndType_info {
    u1 tag; // 12
    u2 name_index; // CONSTANT_Utf8_info
    u2 descriptor_index; // CONSTANT_Utf8_info
    }
  10. CONSTANT_Utf8_info 记录字符串。

    1
    2
    3
    4
    5
    CONSTANT_Utf8_info {
    u1 tag; // 1
    u2 length; // 长度
    u1 bytes[length]; // 字符串数据。
    }
  11. CONSTANT_MethodHandle_info 代表方法句柄

    1
    2
    3
    4
    5
    CONSTANT_MethodHandle_info {
    u1 tag; // 15
    u1 reference_kind; // 1-9的值
    u2 reference_index; // 不同的reference_kind值有不同的行为。
    }
  12. CONSTANT_MethodType_info

    1
    2
    3
    4
    CONSTANT_MethodType_info {
    u1 tag; // 16
    u2 descriptor_index; // CONSTANT_Utf8_info
    }
  13. CONSTANT_InvokeDynamic_info

    1
    2
    3
    4
    5
    CONSTANT_InvokeDynamic_info {
    u1 tag; // 17
    u2 bootstrap_method_attr_index;
    u2 name_and_type_index;
    }

Spark相关

发表于 2018-11-29

概念

  1. 每个Spark的作业都是一个Application。

  2. 每个Application中对应的多个Jobs。

  3. 一个Action操作会触发一个job。(Count,Collect这类)

  4. 每个Job会拆分成多个Stage。(发生shuffle拆分一个stage)

  5. reduceByKey操作会发生shuffle

任务并行度配置

  1. 目前存在2个Executor,总共有20个CPU核心,那么分配的任务数量=20*2.5,即大约50个即可。

什么是Shuffle

记录一次SparkStream中Processing Time时间过长的问题

发表于 2018-11-29

问题的起因很简单,Spark Stream执行的批任务堆积。

第一次排查

  • 通过UI查看了时间消耗问题。发现主要是在代码中执行saveToEs的时候花费了非常的时间。

  • 查看网络连接,发现通信端存在大量的TIME_WAIT状态的连接。

    • 图片显示的数值是调整了访问2个ES节点地址之后的结果,只访问一个的时候会存在1W多个这样的连接状态。

      1
      2
      3
      4
      5
      6
      7
      8
      vi /etc/sysctl.conf

      net.ipv4.tcp_syncookies = 1
      net.ipv4.tcp_tw_reuse = 1
      net.ipv4.tcp_tw_recycle = 1
      net.ipv4.tcp_fin_timeout = 30

      sysctl -p
  • 针对这个情况,暂时没有找到解决的办法,只能推测saveToEsWithMeta这样的函数内部是HTTP短连接每次都会建立新的TCP连接到ES服务器。(还没看源码!)

第二次排查

  • 针对ES提供的库暂时改不了的情况,寻求其它解决办法。

ES常见问题

发表于 2018-11-26
  • ES写入数据可能会出现FORBIDDEN/12/index read-only / allow delete (api)]错误

    相关链接

    这个问题是因为ES的存储空间不够,导致写入数据失败。

    1、调整存储的磁盘空间。然后重启ES程序。

    2、执行以下代码。

    1
    2
    3
    4
    5
    6
    7
    8
    PUT _settings
    {
    "index": {
    "blocks": {
    "read_only_allow_delete": "false"
    }
    }
    }

Hadoop常见异常

发表于 2018-11-12 | 更新于 2018-11-29

服务器异常断电的情况下,重启Hadoop会提示块异常进入安全模式。

  1. 先执行 hdfs dfsadmin -safemode leave 退出安全模式。

  2. 后执行 hdfs fsck /logminer/checkpoint/172.17.0.4_12a69c556cad 查看损坏的块。

  3. 后执行 hdfs fsck -delete /logminer/checkpoint/172.17.0.4_12a69c556cad 对应的块数据。

意外删除副本机器上的Hadoop数据目录解决版本

  1. 先从正常的机器拷贝Datanode节点数据到删除的副本机器上。

  2. 停止在直接启动集群,会出现以下错误。

  3. 修改/home/hadoop/data/dfs/datanode/current/VERSION文件的datanodeUuid,只要改一位就可以。

GO加密模块

发表于 2018-11-08

常见模块

Keyed-Hash Message Authentication Code 密钥哈希消息认证码

  • HMac 使用密钥对消息签名的算法。

    这个算法,就是在计算哈希的时候,嵌入一个密钥,对MD5,SHA算法都有用,本质上这个算法,就是提供一个SHA(message + salt)的通用计算公式。

1
2
3
4
5
6
func hmacSign(key string, message string) {
mac := hmac.New(md5.New, []byte(key))
mac.Write([]byte(message))
expectedMAC := mac.Sum(nil)
fmt.Println(hex.EncodeToString(expectedMAC))
}

哈希计算 MD5

  • 这个没什么说的,不建议使用的方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 计算字符串MD5
data := []byte("These pretzels are making me thirsty.")
fmt.Printf("%x", md5.Sum(data))

// 计算字符串MD5
h := md5.New()
h.Write([]byte("These pretzels are making me thirsty."))
io.WriteString(h, "The fog is getting thicker!")
io.WriteString(h, "And Leon's getting laaarger!")
fmt.Printf("%x", h.Sum(nil))

// 计算文件MD5
f, err := os.Open("file.txt")
if err != nil {
log.Fatal(err)
}
defer f.Close()
h := md5.New()
if _, err := io.Copy(h, f); err != nil {
log.Fatal(err)
}
fmt.Printf("%x", h.Sum(nil))

随机数生成 rand

  • 在Linux上使用getrandom(2) 否则从/dev/urandom获取。

  • By default, getrandom() draws entropy from the urandom source (i.e.,
    the same source as the /dev/urandom device). This behavior can be
    changed via the flags argument.

  • OpenBSD 使用getentropy(2)

  • 其它Unix-like systems从/dev/urandom生成

  • Windows上使用CryptGenRandom API生成

1
2
3
4
nonce := make([]byte, 12)
io.ReadFull(rand.Reader, nonce)

rand.Read(b)//此方法等价于上面的调用。

块加密算法 rc4

  • 不安全的加密算法,不建议使用,这个是加密算法最早用在流式加密中。
1
2
3
4
5
6
7
8
9
ciper, err := rc4.NewCipher([]byte("HelloWorld"))
if nil != err {
panic(err)
}

plaintext := "RC4AAAAAAAAAA"
buffer := make([]byte, len(plaintext))
ciper.XORKeyStream(buffer, []byte(plaintext))
fmt.Println(buffer)

关于Openresty的一些事情

发表于 2018-11-02

在对Openresty这块理解很初级的时候,写的一些脚本存在的低级错误。

  • 把一些状态存储在lua的对象中,在收到请求的时候把对象内的值修改。这个操蛋的做法有什么问题?

    1. 这么做,当前你只有一个nginx工作进程,并且lua_code_cache on;的时候,居然是可以用的。

    2. 并且在Window环境下,你会发现大部分情况都是居然可以用的。

    3. 在多个进程的情况下,你处理请求的进程只是其中一个,在修改对应的变量的时候,只会修改掉接收到请求的进程中的Lua对象值。这个时候就会出现,有的请求返回的值是正确的,有的不正确。

    4. 在代码缓存是off的时候,每次都会去重新载入代码文件,行为也会存在问题。

      所以针对可变的配置内容,不要写在lua文件中,nginx在尝试写入文件的时候,往往都会遇到权限问题,导致不能更新,因此对于动态配置的信息,存储到redis或者其它数据库中。如果实在不想加入数据库。那么可以存储到nginx的共享内存中去。

  • 在Window下ngx.worker.id()的值都是0值。

    1. 如果定时任务,只在一个进程中执行即可,如果多个进程会导致多次执行。

      第一版本:

    2. 在共享内存中存储pid的标志位,只有第一个设置共享内存的进程执行后续的定时任务。后续的进行运行到此代码的时候,获取pid标志位存在的,就退出,这个也是有毛病的。

    3. 因为当我们去执行nginx -s reload的时候,共享内存的值是存在的,这个就会导致定时任务后续就不再执行了。

      第二版本:

    4. 因为nginx的多个进程启动速度是比较快的。通过设置一个时间到共享内存中。通过判断时间间隔小于5秒的值全部退出掉。

      第三版本:

    5. 没有了,如果有希望大神发个邮件给我,在此先感谢了。

Lua编译

发表于 2018-11-02

安装过程

  • 下载源码解压,执行make linux

  • 提示readline找不到,执行apt-get install libreadline-dev

  • 提示ncurses找不到,执行apt-get install libncurses5-dev

123

ideath@operatorworld.com

24 日志
© 2019 ideath@operatorworld.com
由 Hexo 强力驱动 v3.8.0
|
主题 – NexT.Muse v6.4.2