├── .gitignore ├── README.md ├── _config.yml ├── aerospike ├── docs │ ├── README.md │ ├── benchmark.md │ ├── data_model.md │ ├── index.md │ └── overview.md └── img │ ├── arch.png │ └── model_namespace_small.png ├── ceph ├── cmd.md └── intro.md ├── data_analyse └── install_scipy_and_sklearn.md ├── docker ├── Dockerfile │ ├── jupyter_notebook_config.py │ ├── run_jupyter.sh │ ├── start-notebook.sh │ ├── tensorflow_cpu_Dockerfile │ └── tensorflow_gpu_Dockerfile ├── README.md ├── docker_ssh.md ├── docker_underlying_tech.md ├── dockerfile_cmd.md ├── dockerfile优化.md ├── gpu_image_pre.md ├── image │ ├── arch.png │ ├── linux_2.png │ ├── linux_3.png │ ├── linux_4.png │ ├── linux_5.png │ ├── linux_6.png │ └── linux_fs.png └── overview.md ├── elasticsearch └── install.md ├── flink └── README.md ├── flume ├── note.md └── 配置flume.md ├── hadoop ├── hdfs │ ├── README.md │ ├── WebHDFS与HttpFs.md │ ├── acl.md │ ├── apt_install_hadoop_cdh.md │ ├── build_libhdfs_so.md │ ├── compile_hadoop.md │ ├── compression.md │ ├── ha.md │ ├── hadoop_example.md │ ├── hadoop_install.md │ ├── hadoop_rack.md │ ├── hdfs_guide.md │ ├── hdfs_recovery.md │ ├── krb5 │ │ └── introduction.md │ ├── rebalance.md │ ├── small_files.md │ ├── sourcecode │ │ ├── README.md │ │ ├── datanode.md │ │ └── namenode.md │ ├── switch_namenode.md │ ├── trash.md │ └── tune.md ├── img │ ├── Copy_of_Yarn_mem_params.jpg │ ├── debug_hadoop.png │ ├── debug_hadoop_conf.png │ ├── hdfs_recovery_1.png │ ├── hdfs_recovery_2.jpg │ ├── krbmsg.gif │ ├── rack_topology.png │ ├── rebalance.jpg │ └── secondarynn.png └── mapreduce │ ├── RMContainerAllocator分析.md │ ├── join.md │ ├── mr开发环境.md │ └── shuffle分析.md ├── hbase ├── README.md ├── docs │ ├── debug_hbase_source_code.md │ ├── hbase_architecture.md │ ├── hbase_bloomfilter.md │ ├── hbase_column_family_options.md │ ├── hbase_compaction.md │ ├── hbase_conf.md │ ├── hbase_filter.md │ ├── hbase_hfile.md │ ├── hbase_install.md │ ├── hbase_memstore.md │ ├── hbase_merge.md │ ├── hbase_meta.md │ ├── hbase_mttr.md │ ├── hbase_mvcc.md │ ├── hbase_replication.md │ ├── hbase_retry.md │ ├── hbase_rit.md │ ├── hbase_rpc.md │ ├── hbase_secondary_index.md │ ├── hbase_split.md │ ├── hbase_timeline_consistency.md │ ├── hbase_timeout.md │ ├── hbase_tune.md │ ├── hbase_wal.md │ ├── import_data_into_hbase.md │ ├── lsm.md │ ├── nginx.md │ └── source_code │ │ ├── hbase_sc_split.md │ │ └── hmaster_start.md ├── img │ ├── ObjectLifetime.gif │ ├── build_hbase_conf_conf.jpg │ ├── build_hbase_edit_con.jpg │ ├── build_hbase_new_application.jpg │ ├── build_hbase_run.jpg │ ├── build_hbase_run_shell.jpg │ ├── build_hbase_shell.jpg │ ├── cms.png │ ├── deletion_with_compact.png │ ├── gc_1.png │ ├── gc_2.png │ ├── gc_3.png │ ├── gc_4.png │ ├── gc_5.png │ ├── gc_6.png │ ├── gc_7.png │ ├── gc_8.png │ ├── hbase_arch.png │ ├── hbase_protocal.jpg │ ├── hotspot_heap.png │ ├── hotspot_jvm_architecture.png │ ├── marking.png │ ├── merge_region_networkio.png │ ├── merge_region_num.png │ └── normal_deletion.png └── thrift2_demo │ └── README.md ├── hive ├── hive_add_jars.md ├── hive_cli.md ├── hive_compile.md ├── hive_intro.md ├── hive压缩测试.md ├── hive数据迁移.md ├── note.md └── 乱码.md ├── java ├── IntelliJIDEA_ReferenceCard_Mac.pdf ├── README.md ├── classloader.md ├── concurrency │ ├── README.md │ ├── java_concurrency_in_practice_note_01.md │ ├── java_concurrency_in_practice_note_02.md │ ├── java_concurrency_in_practice_note_03.md │ ├── java_concurrency_in_practice_note_04.md │ └── java_concurrency_in_practice_note_05.md ├── demos │ └── d1 │ │ ├── src │ │ └── samples │ │ │ ├── Animal.java │ │ │ ├── AnimalHandler.java │ │ │ ├── Cat.java │ │ │ ├── Dog.java │ │ │ └── ProxyTest.java │ │ └── testDynamicProxy.iml ├── dynamicProxy.md ├── img │ ├── ObjectLifetime.png │ ├── cms.gif │ ├── deletion_with_compact.png │ ├── gc_1.png │ ├── gc_2.png │ ├── gc_3.png │ ├── gc_4.png │ ├── gc_5.png │ ├── gc_6.png │ ├── gc_7.png │ ├── gc_8.png │ ├── hotspot_heap.png │ ├── hotspot_jvm_architecture.png │ ├── intellij │ │ ├── mvn_tomcat_add.jpg │ │ ├── mvn_tomcat_conf.jpg │ │ ├── mvn_tomcat_edit_con.jpg │ │ └── mvn_tomcat_new.jpg │ ├── java_io_model │ │ ├── asyn_io.png │ │ ├── blocking_io.png │ │ ├── comparison.png │ │ ├── io_multiplexing.png │ │ ├── nonblocking_io.png │ │ └── signal_driven_io.png │ ├── jstl_core_tag.jpg │ ├── jstl_fmt_tag_library.jpg │ ├── jstl_function_tag_library.png │ ├── jstl_sql_tag_library.png │ ├── jstl_xml_tag_library.jpg │ ├── marking.png │ ├── normal_deletion.png │ ├── rpc │ │ └── rpc-component.jpg │ └── staticProxy.gif ├── intellij.md ├── java_memory_model.md ├── java_nio.md ├── java_reflection.md ├── java_socket.md ├── java_static_factory_method.md ├── java_thread.md ├── java_unix_io_model.md ├── jsp.md ├── jvm.md ├── log4j.md ├── maven │ ├── maven.md │ ├── package.md │ └── pom.xml说明.md ├── netty │ ├── intro.md │ └── netty_in_action │ │ └── 01.md ├── rpc.md └── servlet.md ├── kafka ├── docs │ ├── README.md │ ├── developer_setup.md │ ├── intro.md │ └── jmx.md └── imgs │ ├── jmx_1.jpg │ ├── jmx_2.jpg │ └── mem_vs_disk.jpg ├── kubernetes ├── README.md ├── deploy_app.md ├── deploy_gpu.md ├── etc │ ├── apiserver │ ├── config │ ├── etcd.conf │ ├── flanneld │ ├── kubelet │ └── proxy ├── img │ ├── .DS_Store │ ├── arch.png │ ├── dashboard_overview.png │ ├── redis_helloworld.png │ ├── services-iptables-overview.svg │ ├── services-ipvs-overview.svg │ └── services-userspace-overview.svg ├── ins.sh ├── install.md ├── install_by_kubeadm.md ├── install_sum.md ├── intro.md ├── iptables.md ├── k8s_in_action │ ├── README.md │ ├── cobra.md │ └── kube_scheduler.md ├── notes │ ├── 1_prepare.md │ ├── 2_kubectl.md │ ├── 3_apiserver.md │ ├── 4_scheduler.md │ ├── 5_scheduler_extender.md │ ├── 6_controller_manager.md │ ├── 7_informer.md │ ├── 8_device_plugin.md │ ├── client_go.md │ ├── cni.md │ ├── extended_resource.md │ ├── img │ │ ├── device-plugin-overview.png │ │ ├── device-plugin.png │ │ └── visitor-uml.png │ ├── network.md │ ├── ref.md │ └── service.md ├── systemd │ ├── docker.service │ ├── etcd.service │ ├── flanneld.service │ ├── kube-apiserver.service │ ├── kube-controller-manager.service │ ├── kube-proxy.service │ ├── kube-scheduler.service │ └── kubelet.service └── todo.md ├── ml ├── README.md ├── distribute_train │ └── README.md ├── docs │ ├── README.md │ ├── derivative.md │ ├── gd_vs_sgd.md │ ├── king_county.md │ └── mpi │ │ ├── README.md │ │ ├── allgather.png │ │ ├── allreduce.png │ │ ├── barrier.png │ │ ├── broadcastvsscatter.png │ │ ├── gather.png │ │ ├── intro.md │ │ └── reduce.png ├── gpu │ ├── README.md │ ├── gpu.md │ ├── imgs │ │ ├── deep-learning-nvlink-performance-chart-625-udt.png │ │ ├── gpu-direct-rdma-over-infiniband-with-and-without.png │ │ ├── multi-gpu-cpu-parameter-server.png │ │ ├── multi-gpu-multi-gpu-all_reduce.png │ │ ├── multi-node-all_reduce.png │ │ ├── multi-node-asynchronous-distributed-sgd.png │ │ ├── multiple-parameter-servers-distributed.png │ │ ├── nvidia-nvswitch-diagram.jpg │ │ ├── nvidia-nvswitch-diagram.svg │ │ ├── pci.png │ │ ├── pcie-bandwidth.png │ │ ├── pcie-topology.jpg │ │ ├── pcie-vs-pci.png │ │ ├── ring-all_reduce-distributed-training.png │ │ ├── single-gpu.png │ │ ├── synchronous-distributed-sgd.png │ │ ├── tesla-v100-nvlink-gpu-cpu-diagram-625-udt.png │ │ └── tesla-v100-nvlink-hybrid-cube-mesh-diagram-625-udt.png │ ├── multi_gpu_and_multi_node_training.md │ └── pci_pcie_nvlink.md ├── ml-zzh │ ├── README.md │ ├── chapter01-basic.md │ ├── chapter02-model-evaluation.md │ ├── chapter05-neural-networks.md │ └── image │ │ └── 01_01.png └── nccl │ ├── img │ ├── allgather.png │ ├── allreduce.png │ ├── broadcast.png │ ├── reduce.png │ └── reducescatter.png │ └── intro.md ├── monitor ├── README.md ├── cdh_monitor.md ├── hadoop_metrics.md ├── install_ganglia.md ├── linux_metrics.md ├── metrics2.md └── tools.md ├── oozie └── enable_oozie_web_console.md ├── ref.md ├── scala ├── docs │ ├── sbt.md │ └── 语法.md └── imgs │ └── setting-expression.png ├── solr ├── README.md └── solr_intro.md ├── spark ├── README.md ├── spark_guide.md ├── spark_install.md └── submit_python_script.md ├── spring ├── 1_intro.md ├── 2_wring_bean.md ├── 3_aop.md ├── 4_springmvc.md ├── 5_jpa.md ├── config.md ├── img │ └── springmvc_requrest.png └── springboot │ ├── 01_intro.md │ └── README.md ├── sqoop └── sqoop简介.md ├── storm └── storm_tutorial.md ├── tensorflow ├── docs │ ├── README.md │ ├── install_caffe.md │ ├── install_tf.md │ ├── intro.md │ ├── read_data.md │ ├── tfos.md │ └── tfrecord简介.md └── img │ └── tensorflow_programming_environment.png ├── yarn ├── imgs │ ├── nmAppStatus.jpg │ └── nmAppStatus.svg ├── nodemanager_app_status.md ├── scheduler.md └── yarn_tune.md └── zookeeper └── 安装部署.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # bigdata 2 | 本 repo 主要记录工作中学习了解的知识与遇到的问题,权当笔记使用。希望将这些知识应用于工作,毕竟专业知识只有提高生产力或变现才有价值。 3 | 4 | ## TODO 5 | - ML 6 | - TensorFlow -- A 7 | - 机器学习 -- C 8 | - Cloud 9 | - Kubernetes -- A 10 | - Docker -- B 11 | - BigData 12 | - Spark -- B 13 | - Flink -- C 14 | 15 | ## 级别定义 16 | 17 | 级别 | 涵义 18 | -------|----- 19 | A | 主攻方向,做到精。有分享,有博客记录等,能应用到工作中,能讲给别人听懂。 20 | B | 重点学习,理解原理,能熟练应用。 21 | C | 了解原理,熟悉重要操作和基本流程。 22 | D | 大致理解,懂一般流程。 23 | 24 | ## Todo 25 | - [Dubbo](https://github.com/apache/incubator-dubbo) 26 | - Spring 27 | - ML 28 | 29 | ## Doing 30 | - Kubernetes 31 | - Java 32 | 33 | ## Done: 34 | - [压缩](hadoop/hdfs/compression.md) 35 | - [集群调优](hadoop/hdfs/tune.md) 36 | 37 | ## Out 38 | - ~~[HBase off heap]~~ 39 | - ~~[Spark Shuffle]~~ 40 | - ~~[Spark数据倾斜]~~ 41 | - ~~[RPC分析](java/rpc.md)~~ 42 | 43 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /aerospike/docs/README.md: -------------------------------------------------------------------------------- 1 | Q1: smart partition 作用,结构?如果其挂了怎么办? 2 | Q2: record key 的前 12 bit 判断 partition,那 partition 是啥概念,会不会出现 partition 挂掉或丢失的情况。若类似于机器,那机器挂掉的话,怎么用该 key 找到机器? 3 | -------------------------------------------------------------------------------- /aerospike/docs/benchmark.md: -------------------------------------------------------------------------------- 1 | # 使用 YCSB 对 Aerospike 进行基准测试 2 | 3 | -------------------------------------------------------------------------------- /aerospike/docs/data_model.md: -------------------------------------------------------------------------------- 1 | # Data Model 2 | 3 | Aerospike 数据模型不完全符合刚性模式(rigid schema,即需有 database,schema,data type,table 等),对数据类型的变更不需要修改 schema,且能随时添加新的 bin 类型。接下来讨论下 Aerospike 数据模型和存储相关的基本概念。 4 | 5 | ## Namespaces 6 | Namespaces 是最顶层的数据容器,一个 namespace 相当于标准关系型数据库的一部分数据库或一组数据库。一个 namespace 中包含 record,index 和 policies,policies 描述了 namespce 的行为,包括: 7 | - 数据如何存放:存内存还是存磁盘。 8 | - record 的复本数。 9 | - record 何时过期。 10 | 11 | 一个数据库能指定多个 namespaces,每个 namespaces 都有各自对应的 policies。如下图,一个数据库有两个 namespaces:ns1 和 ns2,其中 ns1 将 record 存在磁盘中,ns2 将 record 存在内存中: 12 | 13 | ![Namespaces using different storage engines](../img/model_namespace_small.png) 14 | 15 | ## Sets 16 | Sets 相当于关系型数据库的表,其将多条 records 组织成一个集群。 Sets 继承了 namespace 的 policies,并能添加额外的 policies 和操作。 17 | 18 | ## Records 19 | Records 是数据库的基本存储单元,Records 使用 key 做为唯一标识。Records 由如下形式组成: 20 | 21 | 组件 | 定义 22 | ----|-------- 23 | key | 唯一标识符。通过 hash 后的 key (被称为 digest)可得到该 record 的地址。 24 | metadata | Record 的版本信息(generation)和过期时间(TTL)。 25 | bins | 字段。 26 | 27 | ### Keys 和 Digests 28 | 当 key 被发送给数据库时,key 及 set 信息会做 hash 成为一个 16位的 digest,digest 用于定位 record。 29 | 30 | ### Metadata 31 | 每个 record 都包含如下 metadata: 32 | - generation 33 | generation 跟踪 record 的修改记录,在读取 record 时,generation 会返回给应用端,用于判断距离上次读取时是否有新的修改。 34 | - ttl (time-to-live) 35 | 定义 record 的过期时间。 36 | - lut (last-update-time) 37 | 定义 record 的变更时间。 38 | 39 | ## Bins 40 | 在 record 中,数据存储在一个或多个 bins 中。Bins 由 name 和 value 组成,Bins 不需要指定数据类型,数据类型由存储的 value 定义。 41 | 42 | ## 参考 43 | - [Data Model](https://www.aerospike.com/docs/architecture/data-model.html) 44 | -------------------------------------------------------------------------------- /aerospike/docs/index.md: -------------------------------------------------------------------------------- 1 | # 索引 2 | 3 | ## 主键索引 4 | 主键索引是分布式 hash 表与每台 Aerospike 节点中的分布式树型结构的混合。namespace 中的 key 空间通过 hash 算法分成了 partitions。整个集群共有 4096 个partitions。 5 | 6 | Aerospike 节点上的树结构是红黑树节点,对于每个 partitions,可以有可配置数量的这种红黑树结构,称之为分枝(sprigs)。在设置合适数量的分枝时,需要考虑内存空间和优化并行访问。 7 | 8 | 主键索引位于一个 20 字节的 hash -- 主键索引的的 digest 中,当 record key 的原始大小不到 20 字节时,会对其进行扩展。当一台节点不可用时,其他节点与该节点 key 相同的备份 key 会立即可用,若该故障节点一直不可用,则会进行 rebalance,保证 key 的复本数不变。 9 | 10 | ### 索引的元数据 11 | 目前每个 index 条目大小为 64 字节,除了 20 字节的 digest 外,其他元数据也一样存在索引中: 12 | - write generation:根据主键的所有更新操作,用于解决冲突的更新。 13 | - 过期时间 14 | - 上次更新时间 15 | - 存储地址:数据存储地址。 16 | 17 | ### 索引持久化 18 | 为保证性能,主键索引只存在内存中。当 Aerospike 启动时,会扫描存储上的数据并对所有 partition 重建索引,这点类似 ElasticSearch。为了提高集群启动时间,Aerospike 提供了快速重启功能。快速重启需要设置 Linux 共享内存段(Linux shared memory segment),当重启时,节点会从共享内存中读取并激活索引数据。 19 | 20 | ### 单列优化 21 | 若开启单列(single bin)属性,Aerospike 会使用更少的内存存储数据。当所有单列值类型为 int 或 double 类型时,并且该 namespace 在索引中申明数据时会有更好的优化,此时主键索引中的空间会被复用存储 int 或 double 类型的值,即该 namespace 所需的存储空间只为其主键索引的存储空间。 22 | 23 | ## 二级索引 24 | 25 | ## 参考 26 | - [Primary Index](https://www.aerospike.com/docs/architecture/primary-index.html) 27 | - [Secondary Index](https://www.aerospike.com/docs/architecture/secondary-index.html) 28 | -------------------------------------------------------------------------------- /aerospike/docs/overview.md: -------------------------------------------------------------------------------- 1 | # Architecture Overview 2 | 3 | ## 结构 4 | Aerospike 由以下三层组成: 5 | 6 | ![Aerospike Architecture](../img/arch.png) 7 | 8 | - 客户端层: client 层主要实现了 Aerospike 的各种 APIs、跟踪节点和感知数据保存在集群中的位置等功能。 9 | - 集群和数据分发层:该层主要管理集群内部的通信、自动恢复、复制、跨数据中心的同步、数据平衡和数据迁移。 10 | - 数据存储层:该层主要实现将数据保存到 DRAM 和 Flash 中用于快速检索。 11 | 12 | ### 客户端层 13 | 客户端层的设计主要基于速度方面的考虑。该层主要特点如下: 14 | - 实现了 Aerospike API、client-server 的通信协议和直接同集群通信等功能。 15 | - 根据节点并感觉数据存储位置,能即时接收到集群配置的变更和开启关闭节点。 16 | - 为了提升效率实现了自己的 TCP/IP 连接池。并能检查到集群中低于节点故障级别的失败事务,再重新将这些事务提交到有相同数据备份的节点中。 17 | - 能直接将请求发送到存储数据的节点上。 18 | 19 | 这种架构减少事务延迟,消除开发都需要做的工作,保证应用不需要在节点故障时重启。 20 | 21 | ### 分发层 22 | Aerospike “shared nothing” 架构模式的目的是可靠存储 tb 级别的数据,同时具有自动恢复、复制、跨数据中心同步等功能。这层节点能线形的进行扩充。这层主要有 3 个模块: 23 | - 集群管理模块 24 | 该模块用于跟踪集群中的节点。核心算法是一个基于 Paxos 的 gossip-voting 过程,其主要用于判断节点是不是属于集群。Aerospike 实现了一种特殊的心跳用于监听内部节点之间的通信。 25 | - 数据迁移模块 26 | Aerospike 通过一致性 Hash 算法,将数据分成片并将这些片分配给相应的 owner。当添加/删除节点时,Aerospike 的数据迁移模块会将数据分发到集群中所有节点上,保证每一小块的数据复本能跨数据中心和集群节点分布。 27 | - 事务处理模块 28 | 处理读写请求,并提供一致性和隔离性的保证。该模块主要职责如下: 29 | - 同步/异步复制:对于写提供即时一致性(immediate consistency),将对数据的变更传播给所有复本后再提交数据并返回对果给客户端。 30 | - 代理:当集群配置变更时,在极少数情况下客户端层的配置可能会过期,此时事务处理模块会将请求代理给另外的节点。 31 | - 提供重复数据的解决方案:当集群恢复分区的数据时,事务处理模块能解决同一数据多份复本之间不一致性的冲突,解决方案是配置版本号或过期时间。 32 | 33 | ### 数据存储层 34 | Aerospike 是一个类似传统数据库结构的 kv 型存储。数据存储在 namespaces,类似于 RDBMS 系统中的数据库的概念。在一个 namespace 中,数据被分成 sets (类似 RDBMS 中的数据表),和 records (类似 RDBMS 中的行)。在 set 中的每个 record 都有一个唯一的索引 key,和一个或多个 bins(类似 RDBMS 中的列)用于存放与 record 相关的值。 35 | 36 | > 关系对应表: 37 | > 38 | > | RDBMS | Aerospike 39 | > |--------|-------- 40 | > | Database | Namespace 41 | > | Table | Set 42 | > | Row | Record 43 | > | Column | Bin 44 | 45 | bin 的值是强类型的,其能包括任意支持的数据类型,bin 没有类型概念,因此不同 record 的同一 bin 的值可以是不同类型的。索引(即key,包括一级索引和二级索引)存储在 DRAM 方便快速读取,面值能存储在 DRAM 或 SSD 中。不同的 namespace 能配置不同的存储,因此对于数据量较小的 namespace 可将其值也存储在 DRAM 中, 对数据量大的 namespace 将其值存储在 SSD 中。 46 | 47 | 有几点需要注意的: 48 | - 即使 key 的大小不做限制,每个 key 仍以 64 字节大小高效存储。因此 1 亿量级的 key 仅占用 6.4GB 大小空间。 49 | - 对于传统机械磁盘,设置较大级别的 write block 能尽可能小的优化延迟。 50 | - 碎片管理(Smart Defragmenter)和剔除(Intelligent Evictor)机制能保证 DRAM 中有足够的内存保存数据。 51 | - Smart Defragmenter:跟踪每个 block 的 活动 record 数目,回收活动 record 数目低于最小级别使用的 block。 52 | - Intelligent Evictor:当系统内存高于设置的高水准线时,删除过期的数据并回收内存。每个 namespace 都有配置的过期时间,record 生命时长从最后一次变更开始计算。 53 | 54 | ## 操作 Aerospike 55 | 56 | 和传统关系型数据不同的是,在 Areospike 中,创建和管理数据的几种方式如下: 57 | - 通过配置初始 namespace 设置:在安装 Aerospike 时,集群中每个节点的 namespace 都必须配置如何创建和复制 namespace,在启动 server 时会创建 namespace。 58 | - 通过操作 namespace : 59 | - 首次涉及到 set 和 bin 时,会创建namespace 的 schema。 60 | - Aerospike 的 namespace 是一个弹性的 schema,即在需要添加新的 bin 时,只需要将值保存到指定的 bin 上即可。 61 | - 通过更新配置文件:只需修改配置文件即可更新 namespace 的参数。 62 | 63 | Aerospike 同时提供了 [管理组件](https://www.aerospike.com/docs/amc/index.html) 和 [监控工具](https://www.aerospike.com/docs/operations/monitor/index.html) 用于节点管理。当增删节点时,集群会自动重新配置。 64 | 65 | ## 创建应用 66 | 定义好 namespace 后,就能使用 Aerospike 提供的工具判断数据是否被正确存储。为执行操作,使用 Smart Client 来实例化应用,Smart Client 拥有位置感知能力,其在不影响性能的情况下知道如何存储和获取数据。 67 | 68 | ## 参考 69 | - [Architecture Overview](https://www.aerospike.com/docs/architecture/index.html) 70 | -------------------------------------------------------------------------------- /aerospike/img/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/aerospike/img/arch.png -------------------------------------------------------------------------------- /aerospike/img/model_namespace_small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/aerospike/img/model_namespace_small.png -------------------------------------------------------------------------------- /ceph/cmd.md: -------------------------------------------------------------------------------- 1 | # Ceph 基本操作速查 2 | 3 | ## 容量 4 | 5 | - ceph df 6 | 7 | 8 | ## Pool 操作 9 | 10 | 11 | ## rbd 12 | 13 | - map: `rbd map -p ` 14 | - unmap: `rbd unmap ` 15 | 16 | ## 参考 17 | - [Ceph Pool操作总结](http://int32bit.me/2016/05/19/Ceph-Pool%E6%93%8D%E4%BD%9C%E6%80%BB%E7%BB%93/) 18 | -------------------------------------------------------------------------------- /data_analyse/install_scipy_and_sklearn.md: -------------------------------------------------------------------------------- 1 | # 安装numpy,scipy和sklearn 2 | 3 | 本来以为单纯pip就ok的,结果发现有一些依赖,所以这里主要记录下要安装的包,以免之后同样的需求还要上网查找。 4 | 5 | ## 升级Python 6 | centos6.4默认安装的python版本是2.6的,这里先将其升级。过程如下。 7 | 8 | - 安装开发工具包 9 | 命令为`yum groupinstall "Development tools"`。 10 | 11 | - 安装部分包 12 | 命令:`yum install -y zlib-devel openssl-devel bzip2-devel ncurses-devel sqlite-devel gcc gcc-c++`。 13 | 14 | - 安装python 15 | 下载[python](https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz),解压并安装。 16 | ``` 17 | # ./configure --prefix=/usr/local/python-2.7.11 18 | # make;make install 19 | # cd /usr/local 20 | # ln -s python-2.7.11 python 21 | ``` 22 | 编辑`/etc/bashrc`,添加`export PATH=/usr/local/python/bin:$PATH`,source该文件后查看python版本。 23 | 24 | 若`export PATH=$PATH:/usr/local/python/bin`,则python版本仍为2.6,还需要修改`/usr/bin/python`指向,并修改`/usr/bin/yum`中python指向。 25 | 26 | ## 安装setuptools和pip 27 | 28 | 这里是简单的安装,略过。 29 | 30 | ## 安装numpy,scipy,sklearn 31 | 如下: 32 | ``` 33 | # pip install numpy scipy sklearn 34 | # python -c "import numpy; print numpy.__version__" 35 | ``` 36 | 37 | Done。 38 | 39 | ## python2.6安装问题 40 | 41 | 使用python2.6安装,有诸多依赖和问题,使用python2.7安装,问题都没了。对于python2.6,在安装sklearn时报错: 42 | ``` 43 | ImportError: Your installation of Scientific Python (SciPy) 0.7.2 is out-of-date. 44 | scikit-learn requires SciPy >= 0.9. 45 | ``` 46 | 而在安装SciPy报错如下: 47 | ``` 48 | Running setup.py install for SciPy ... error 49 | Complete output from command /usr/bin/python -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-Z9sinw/SciPy/setup.py';exec(compile(getattr(tokenize, 'open', open)(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-5jtzmZ-record/install-record.txt --single-version-externally-managed --compile: 50 | lapack_opt_info: 51 | openblas_lapack_info: 52 | libraries openblas not found in ['/usr/local/lib64', '/usr/local/lib', '/usr/lib64', '/usr/lib'] 53 | NOT AVAILABLE 54 | ``` 55 | 可先将依赖安装好,或安装较高版本的scipy:`pip install --upgrade SciPy==0.10`,然后再安装sklearn。 56 | 57 | 58 | ** UPDATE **:发现CDH提供了这些包,在Remote Parcel Repository URLs中添加`https://repo.continuum.io/pkgs/misc/parcels/`,下载发布,修改/etc/bashrc,添加`export PATH=/opt/cloudera/parcels/Anaconda/bin:$PATH`。另外,对于部分,还需要执行`ln -s /opt/cloudera/parcels/Anaconda-/lib/libpython2.7.so.1.0 /usr/lib64/libpython2.7.so`,以免出现`/usr/bin/ld: cannot find -lpython2.7`。 59 | -------------------------------------------------------------------------------- /docker/Dockerfile/jupyter_notebook_config.py: -------------------------------------------------------------------------------- 1 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | import os 16 | from IPython.lib import passwd 17 | 18 | c.NotebookApp.ip = '*' 19 | c.NotebookApp.port = int(os.getenv('PORT', 8888)) 20 | c.NotebookApp.open_browser = False 21 | c.MultiKernelManager.default_kernel_name = 'python2' 22 | 23 | # sets a password if PASSWORD is set in the environment 24 | if 'PASSWORD' in os.environ: 25 | password = os.environ['PASSWORD'] 26 | if password: 27 | c.NotebookApp.password = passwd(password) 28 | else: 29 | c.NotebookApp.password = '' 30 | c.NotebookApp.token = '' 31 | del os.environ['PASSWORD'] 32 | -------------------------------------------------------------------------------- /docker/Dockerfile/run_jupyter.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2015 The TensorFlow Authors. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ============================================================================== 16 | 17 | USER=jovyan 18 | 19 | chown $USER:users /home/$USER/work 20 | 21 | su -c "jupyter notebook '$@'" -m $USER 22 | -------------------------------------------------------------------------------- /docker/Dockerfile/start-notebook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) Jupyter Development Team. 3 | # Distributed under the terms of the Modified BSD License. 4 | 5 | set -e 6 | 7 | USER=jovyan 8 | 9 | chown $USER:users /home/$USER/work 10 | 11 | su -c "export PATH=/opt/conda/bin/:$PATH;. /usr/local/bin/start.sh jupyter notebook $*" -m $USER 12 | -------------------------------------------------------------------------------- /docker/Dockerfile/tensorflow_cpu_Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jupyter/scipy-notebook:latest 2 | 3 | # reference: https://github.com/jupyter/docker-stacks/blob/master/tensorflow-notebook/Dockerfile 4 | 5 | # python 2.7 6 | RUN conda create --quiet --yes -p $CONDA_DIR/envs/python2 -c conda-forge python=2.7 \ 7 | ipython=4.0* \ 8 | ipywidgets=4.0* \ 9 | seaborn \ 10 | sympy=0.7* \ 11 | cython=0.22* \ 12 | patsy \ 13 | statsmodels \ 14 | cloudpickle \ 15 | dill \ 16 | numba \ 17 | bokeh \ 18 | pyzmq \ 19 | Pillow \ 20 | ipykernel \ 21 | h5py \ 22 | jupyter \ 23 | kernda=0.2 \ 24 | protobuf=3.4.0 \ 25 | tensorflow=1.3 \ 26 | keras=2.0 \ 27 | numpy \ 28 | pandas \ 29 | scipy \ 30 | scikit-learn \ 31 | scikit-image \ 32 | matplotlib && \ 33 | conda clean -tipsy && \ 34 | fix-permissions $CONDA_DIR 35 | 36 | # python 3 37 | RUN conda install --quiet --yes \ 38 | tensorflow=1.3* \ 39 | numpy \ 40 | keras=2.0* && \ 41 | conda clean -tipsy && \ 42 | fix-permissions $CONDA_DIR 43 | 44 | USER root 45 | 46 | RUN $CONDA_DIR/envs/python2/bin/python -m ipykernel install && \ 47 | $CONDA_DIR/envs/python2/bin/kernda -o -y /usr/local/share/jupyter/kernels/python2/kernel.json 48 | 49 | USER $NB_USER 50 | 51 | WORKDIR $HOME/work 52 | 53 | ADD start-notebook.sh /usr/local/bin/ 54 | 55 | CMD ["sh", "-c", "start-notebook.sh"] 56 | -------------------------------------------------------------------------------- /docker/Dockerfile/tensorflow_gpu_Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nvidia/cuda:8.0-cudnn6-devel-ubuntu16.04 2 | 3 | # reference: https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/tools/docker/Dockerfile.gpu 4 | 5 | ENV NB_USER=jovyan \ 6 | NB_UID=1000 \ 7 | NB_GID=100 8 | 9 | # Pick up some TF dependencies 10 | RUN sed -i 's/http:\/\/archive\.ubuntu\.com\//http:\/\/mirrors\.aliyun\.com\//g' /etc/apt/sources.list && \ 11 | apt-get update && \ 12 | apt-get install -y --no-install-recommends \ 13 | build-essential \ 14 | curl \ 15 | libssl-dev \ 16 | libffi-dev \ 17 | libfreetype6-dev \ 18 | libpng12-dev \ 19 | libzmq3-dev \ 20 | pkg-config \ 21 | python \ 22 | python-dev \ 23 | python-pip \ 24 | python-setuptools \ 25 | python3 \ 26 | python3-dev \ 27 | python3-pip \ 28 | python3-setuptools \ 29 | rsync \ 30 | software-properties-common \ 31 | unzip \ 32 | vim && \ 33 | apt-get clean && \ 34 | rm -rf /var/lib/apt/lists/* 35 | 36 | # Python 2 37 | RUN pip install --no-cache-dir -i http://pypi.doubanio.com/simple --trusted-host=pypi.doubanio.com \ 38 | setuptools \ 39 | ipython==5.5.0 \ 40 | ipywidgets \ 41 | mock \ 42 | seaborn \ 43 | sympy \ 44 | cython \ 45 | patsy \ 46 | statsmodels \ 47 | cloudpickle \ 48 | dill \ 49 | numba \ 50 | bokeh \ 51 | pyzmq \ 52 | Pillow \ 53 | ipykernel \ 54 | h5py \ 55 | jupyter \ 56 | matplotlib \ 57 | numpy \ 58 | pandas \ 59 | scipy \ 60 | sklearn \ 61 | scikit-image \ 62 | keras \ 63 | protobuf && \ 64 | pip install --no-cache-dir http://pypi.doubanio.com/packages/ca/c4/e39443dcdb80631a86c265fb07317e2c7ea5defe73cb531b7cd94692f8f5/tensorflow_gpu-1.3.0-cp27-cp27mu-manylinux1_x86_64.whl#md5=c476a9ae1227fb072a781866bd77e7f7 && \ 65 | python -m ipykernel install 66 | 67 | # Python 3 68 | RUN pip3 install --no-cache-dir -i http://pypi.doubanio.com/simple --trusted-host=pypi.doubanio.com \ 69 | ipywidgets \ 70 | mock \ 71 | seaborn \ 72 | sympy \ 73 | cython \ 74 | patsy \ 75 | statsmodels \ 76 | cloudpickle \ 77 | dill \ 78 | numba \ 79 | bokeh \ 80 | pyzmq \ 81 | Pillow \ 82 | h5py \ 83 | jupyter \ 84 | matplotlib \ 85 | numpy \ 86 | pandas \ 87 | scipy \ 88 | sklearn \ 89 | scikit-image \ 90 | keras \ 91 | protobuf && \ 92 | pip3 install --no-cache-dir http://pypi.doubanio.com/packages/ad/bd/bb96a3203296fa4400e51068d48824efeb72922a5608300bdcceafb38eaa/tensorflow_gpu-1.3.0-cp35-cp35m-manylinux1_x86_64.whl#md5=5c1a79023cf04f1b4964595bf769b8a4 93 | 94 | RUN useradd -m -s /bin/bash -N -u $NB_UID $NB_USER 95 | 96 | ENV LD_LIBRARY_PATH=/usr/local/cuda/extras/CUPTI/lib64:/usr/lib64/nvidia:$LD_LIBRARY_PATH \ 97 | HOME=/home/$NB_USER 98 | 99 | USER $NB_USER 100 | 101 | RUN mkdir /home/$NB_USER/work 102 | 103 | # Set up our notebook config. 104 | COPY jupyter_notebook_config.py $HOME/.jupyter/ 105 | 106 | USER root 107 | 108 | COPY run_jupyter.sh / 109 | 110 | EXPOSE 8888 6006 111 | 112 | WORKDIR $HOME/work 113 | 114 | CMD ["sh", "-c", "/run_jupyter.sh", "--allow-root"] 115 | -------------------------------------------------------------------------------- /docker/README.md: -------------------------------------------------------------------------------- 1 | ## Catalog 2 | 3 | - containerd (http://blog.daocloud.io/docker-1-11-et-plus-engine-is-now-built-on-runc-and-containerd/) 4 | - libcontainer --> runC (http://dockone.io/article/776) 5 | 6 | Docker Engine 仍负责镜像管理,将镜像交付到 containerd 运行,containerd 使用 runC 来运行容器 7 | -------------------------------------------------------------------------------- /docker/docker_ssh.md: -------------------------------------------------------------------------------- 1 | # 创建 ssh 登录的 docker 镜像 2 | 3 | 由于需要使用 ssh 登录 docker 容器,或使用 sftp 上传下载文件,需要能以 ssh 登录容器,这里以 centos 为例,说下过程。 4 | 5 | 若想以 ssh 登录,需要以 centos 为基础新创建一个容器,主要参考 [SSH-Centos7-Dockerfile](https://github.com/CentOS/CentOS-Dockerfiles/tree/master/ssh/centos7)。 6 | 7 | Dockerfile 如下: 8 | ``` 9 | FROM centos:centos7 10 | 11 | RUN yum -y update; yum clean all 12 | RUN yum -y install openssh-server passwd; yum clean all 13 | RUN mkdir /var/run/sshd 14 | 15 | RUN ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' 16 | 17 | # EXPOSE 22 18 | ENV USER jovyan 19 | ENV SSH_PASSWD 123 20 | 21 | COPY start.sh /start.sh 22 | 23 | RUN ./start.sh $USER $SSH_PASSWD 24 | ENTRYPOINT ["/usr/sbin/sshd", "-D"] 25 | ``` 26 | 27 | start.sh 如下: 28 | ``` 29 | #!/bin/bash 30 | 31 | __create_user() { 32 | # Create a user to SSH into as. 33 | 34 | USER=$1 35 | SSH_USERPASS=$2 36 | useradd $USER 37 | echo -e "$SSH_USERPASS\n$SSH_USERPASS" | (passwd --stdin $USER) 38 | echo $USER user password: $SSH_USERPASS 39 | } 40 | 41 | # Call all functions 42 | __create_user $1 $2 43 | ``` 44 | 设置该脚本权限为 `755`。 45 | 46 | 然后按以下步骤操作: 47 | - 打包:`# docker build --rm -t centos7:ssh .`。 48 | - 运行容器:`# docker run -d -p 22 centos7:ssh`。 49 | - 获取容器端口信息: 50 | ``` 51 | # docker ps 52 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 53 | 8c82a9287b23 centos7:ssh /usr/sbin/sshd -D 4 seconds ago Up 2 seconds 0.0.0.0:49154->22/tcp mad_mccarthy 54 | ``` 55 | - 通过 ssh 登录:`# ssh -p xxxx jovyan@localhost`。 56 | - 通过 sftp 登录:`sftp -oPort=xxxx jovyan@localhost`。 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /docker/dockerfile_cmd.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - [RUN vs CMD vs ENTRYPOINT](https://www.ibm.com/developerworks/community/blogs/132cfa78-44b0-4376-85d0-d3096cd30d3f/entry/RUN_vs_CMD_vs_ENTRYPOINT_%E6%AF%8F%E5%A4%A95%E5%88%86%E9%92%9F%E7%8E%A9%E8%BD%AC_Docker_%E5%AE%B9%E5%99%A8%E6%8A%80%E6%9C%AF_17?lang=en) 4 | -------------------------------------------------------------------------------- /docker/dockerfile优化.md: -------------------------------------------------------------------------------- 1 | # 优化 Dockerfile,减小镜像大小。 2 | 3 | ## 删除不必要文件 4 | 在 apt 下载软件后,可执行 `apt-get clean` 和 `rm -rf /var/lib/apt/lists/*` 删除包缓存中的所有 .deb 文件包;另外,apt-get install 过程中会加入很多可有可无的依赖,这部分不必要的内容可通过指定`--no-install-recommends` 不安装,如下: 5 | ``` 6 | RUN apt-get udpate && \ 7 | apt-get install -y --no-install-recommends python-pip && \ 8 | apt-get clean && \ 9 | rm -rf /var/lib/apt/lists/* 10 | ``` 11 | 12 | 对于 pip 安装的包,可通过 `pip --no-cache-dir install` 指定不缓存文件。另外,对于从官网下载源,速度无疑太慢了,通常制作镜像时间大部分卡在这里,使用国内镜像源,能极大提升制作镜像的时间。这里推荐使用豆瓣的镜像。使用方法为:`pip install -i http://pypi.douban.com/simple/ --trusted-host=pypi.doubanio.com numpy`。 13 | 14 | 对于 ADD/COPY 拷贝的安装文件,在安装完成后,记得再将这些文件删除。 15 | 16 | 不过在测试 Dockerfile 中,先不要加上这些参数,以免因其他逻辑错误导致重复下载这些包,耗时太久。 17 | 18 | - [Dockerfile Best Practices](http://crosbymichael.com/dockerfile-best-practices.html) 19 | -------------------------------------------------------------------------------- /docker/gpu_image_pre.md: -------------------------------------------------------------------------------- 1 | # 制作 GPU 镜像须知 2 | 如下几个包需安装: 3 | - [cudnn](https://developer.nvidia.com/cudnn) 4 | - [nccl](https://github.com/NVIDIA/nccl) 5 | - [cuBLAS](https://developer.nvidia.com/cublas) 6 | 7 | 官方 dockerfile 中已经安装了如上几个包了 8 | 9 | CUDA_HOME 需设置。 10 | -------------------------------------------------------------------------------- /docker/image/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/arch.png -------------------------------------------------------------------------------- /docker/image/linux_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_2.png -------------------------------------------------------------------------------- /docker/image/linux_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_3.png -------------------------------------------------------------------------------- /docker/image/linux_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_4.png -------------------------------------------------------------------------------- /docker/image/linux_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_5.png -------------------------------------------------------------------------------- /docker/image/linux_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_6.png -------------------------------------------------------------------------------- /docker/image/linux_fs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/docker/image/linux_fs.png -------------------------------------------------------------------------------- /docker/overview.md: -------------------------------------------------------------------------------- 1 | # Docker Overview 2 | 3 | ## 基本命令 4 | 5 | ### 进入正在运行的 docker 6 | 有如下几种方式可进入正在的 docker 容器中: 7 | - docker exec 8 | - docker attach 9 | 这种方式一般不推荐使用,因为一般通过该命令进入的容器后,若退出该命令,则该容器也会退出。 10 | 11 | ### 设置代理 12 | 13 | `sudo docker build --build-arg HTTPS_PROXY=http://proxy:port - < Dockerfile` 14 | 15 | 16 | 清除非正在运行的: 17 | `docker system prune -a` 18 | -------------------------------------------------------------------------------- /elasticsearch/install.md: -------------------------------------------------------------------------------- 1 | 做如下修改: 2 | 3 | /etc/sysctl.conf 4 | 5 | ``` 6 | vm.swappiness=1 7 | fs.file-max=4294836225 8 | vm.max_map_count=262144 9 | ``` 10 | 11 | /etc/security/limits.d/90-nproc.conf 12 | ``` 13 | es - noproc unlimited 14 | es - nofile 65536 15 | es - memlock unlimited 16 | ``` 17 | 18 | /opt/elasticsearch/config/elasticsearch.yaml: 19 | ``` 20 | cluster.name: elasticsearch_hbase_online 21 | node.name: bd15-094.yzdns.com 22 | path.data: /hadoop/es/data,/hadoop1/es/data,/hadoop2/es/data,/hadoop3/es/data,/hadoop4/es/data,/hadoop5/es/data,/hadoop6/es/data,/hadoop7/es/data,/hadoop8/es/data,/hadoop9/es/data,/hadoop10/es/data,/hadoop11/es/data 23 | path.logs: /var/log/es 24 | bootstrap.memory_lock: true 25 | network.host: 10.6.28.26 26 | http.port: 9200 27 | discovery.zen.ping.unicast.hosts: ["10.6.28.24", "10.6.28.25", "10.6.28.26"] 28 | discovery.zen.minimum_master_nodes: 2 29 | gateway.recover_after_nodes: 3 30 | gateway.expected_nodes: 3 31 | gateway.recover_after_time: 3m 32 | action.destructive_requires_name: true 33 | ``` 34 | 35 | ``` 36 | # mkdir /hadoop{,1,2,3,4,5,6,7,8,9,10,11}/es 37 | # chown -R es:es /hadoop{,1,2,3,4,5,6,7,8,9,10,11}/es 38 | ``` 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /flink/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | ## 参考 4 | - [Streaming 101: The world beyond batch](https://www.oreilly.com/ideas/the-world-beyond-batch-streaming-101) 5 | - [超越批处理的世界:流计算101](https://www.oreilly.com.cn/ideas/?p=18) 6 | - [流式超越批量:Streaming 102翻译](https://limuzhi.com/2017/04/09/%E6%B5%81%E5%BC%8F%E8%B6%85%E8%B6%8A%E6%89%B9%E9%87%8F-Streaming%20102%E7%BF%BB%E8%AF%91/) 7 | 8 | - [flink-streaming-demo](https://github.com/dataArtisans/flink-streaming-demo) 9 | - [Flink 零基础实战教程:如何计算实时热门商品](http://wuchong.me/blog/2018/11/07/use-flink-calculate-hot-items/) 10 | 11 | -------------------------------------------------------------------------------- /flume/note.md: -------------------------------------------------------------------------------- 1 | # Flume相关的一些笔记 2 | 3 | ## Source 4 | 5 | 若source为kafka,其已存在数据,若希望flume重头开始("from-begingin")读取数据,可通过重新设置新comsume组来实现。若zookeeper中偏移数据为空或便宜数据进出范围,可通过设置[auto.offset.reset](https://kafka.apache.org/08/configuration.html#consumerconfigs)为`smallest`或`readSmallestOffset`为`true`来重头读取。 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /hadoop/hdfs/README.md: -------------------------------------------------------------------------------- 1 | ## 目录 2 | 3 | - [Hadoop Rack Awareness](hadoop_rack.md) 4 | - [Hadoop Balancer](rebalance.md) 5 | - [Trash](trash.md) 6 | - [Hadoop 调优](tune.md) 7 | - [Hadoop 压缩](compression.md) 8 | - [Hadoop 权限](acl.md) 9 | - [Hadoop Recovery](hdfs_recovery.md) 10 | - [编译 Hadoop 源码](compile_hadoop.md) 11 | -------------------------------------------------------------------------------- /hadoop/hdfs/WebHDFS与HttpFs.md: -------------------------------------------------------------------------------- 1 | WebHDFS vs HttpFS 2 | --- 3 | 4 | HDFS提供Java Native API用以高效的访问HDFS,对于Hadoop集群外的客户端访问Hadoop集群,不大可能都去安装hadoop和java库。所以为解决这一问题,出现了WebHDFS和HttpFS。HttpFS由cloudera开发并捐给Apache,WebHDFS由hortonworks开发并捐给Apache。 5 | 6 | 相同点 7 | === 8 | - 目的都是让Hadoop集群外的应用程序,不需要安装Java和Hadoop库,即可访问访问集群。 9 | - 都通过HTTP方法支持Hadoop的读写操作,可用于代替HFTP(只读文件系统,通常配合distcp用于不同版本的Hadoop集群间拷贝数据)。 10 | - 提供了一套REST API操作,该API不随Hadoop版本变化而变化,能在不同版本的Hadoop集群间拷贝数据。两者REST API能兼容。 11 | - 都支持kerbose等验证方式。 12 | 13 | 不同点 14 | === 15 | - WebHDFS通过HTTP方法支持Hadoop所有操作,如读写文件和创建目录等。 16 | - WebHDFS有 **Data Locality** 的特性,对HDFS文件的读写,会重定向到文件所在的DataNode,并会完全利用HDFS的带宽。 17 | - 目前WebHDFS已是HDFS的内置组件。而HttpFS还需要单独启动该服务。 18 | - HttpFS相当于一个gateway的功能,对于大流量的应用,HttpFS可能会是瓶颈。对于一些非核心用户,正好需要通过HttpfFS来限制带宽。 19 | 20 | 应用 21 | === 22 | 当业务部门需要使用Hadoop集群时,可使用HttpFS服务。而在大批量拷贝数据时,可通过开启多个WebHDFS进程完全利用带宽来加速拷贝。 23 | 24 | 参考 25 | === 26 | - [WebHDFS – HTTP REST Access to HDFS](http://zh.hortonworks.com/blog/webhdfs-%E2%80%93-http-rest-access-to-hdfs/) 27 | - [Hadoop HDFS over HTTP - Documentation Sets 2.0.0-cdh4.7.0](http://archive.cloudera.com/cdh4/cdh/4/hadoop/hadoop-hdfs-httpfs/index.html) 28 | - [Accessing HDFS using the WebHDFS REST API](https://www.linkedin.com/pulse/20140717115238-176301000-accessing-hdfs-using-the-webhdfs-rest-api-vs-httpfs) 29 | - [About HttpFS](http://www.cloudera.com/documentation/archive/cdh/4-x/4-7-1/CDH4-Installation-Guide/cdh4ig_topic_25_1.html) 30 | - [WebHDFS REST API](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/WebHDFS.html) 31 | -------------------------------------------------------------------------------- /hadoop/hdfs/acl.md: -------------------------------------------------------------------------------- 1 | ## 权限 2 | 3 | ### ACL 4 | 参考[linux文件权限说明](https://github.com/mattshma/docs/blob/master/linux/linux%E6%96%87%E4%BB%B6%E6%9D%83%E9%99%90%E8%AF%B4%E6%98%8E.md),对linux权限位有个了解。在Hadoop中, 5 | 6 | ls的权限位输出以+结束时,那么该文件或目录正在启用一个ACL。在配置文件中需要先开启acl: 7 | 8 | ``` 9 | 10 | dfs.namenode.acls.enabled 11 | true 12 | 13 | ``` 14 | 15 | 以用户ma(user:ma,group:ma)为例,在linux shell中相关命令如下: 16 | ``` 17 | # 添加acl 18 | hdfs dfs -setfacl -R -m user:ma:r-x /user/hive/warehouse/test.db 19 | # 删除acl 20 | hdfs dfs -setfacl -x user:ma /user/hive/warehouse/test.db 21 | ``` 22 | 23 | 还可以定义 default acl 条目,新的子文件和子目录会自动继承 default acl 条目设置。只有目录才能设置 default acl 条目。如下: 24 | 25 | ``` 26 | hdfs dfs -setfacl -m default:group:ma:r-x /user/hive/warehouse/test.db 27 | ``` 28 | 29 | ### mask 30 | mask限定了用户能拥有的最大权限,即在不改变ACL定义的基础上,通过修改mask来提高/降低安全级别,如下: 31 | ``` 32 | # hdfs dfs -getfacl /user/mam 33 | # file: /user/mam 34 | # owner: mam 35 | # group: mam 36 | user::rwx 37 | group::rwx 38 | mask::rwx 39 | other::r-x 40 | default:user::rwx 41 | default:user:bob:rwx 42 | default:group::rwx 43 | default:mask::rwx 44 | default:other::r-x 45 | 46 | # hdfs dfs -getfacl /user/mam/test 47 | # file: /user/mam/test 48 | # owner: mam 49 | # group: mam 50 | user::rwx 51 | user:bob:rwx #effective:r-x 52 | group::rwx #effective:r-x 53 | mask::r-x 54 | other::r-x 55 | default:user::rwx 56 | default:user:bob:rwx 57 | default:group::rwx 58 | default:mask::rwx 59 | default:other::r-x 60 | ``` 61 | 从上可以看到,对于用户bob而言,即使acl设置了为rwx,但由于mask为r-x,所以实际权限仍为r-x。 62 | 63 | ### Group Mapping 64 | 给定一个用户,通过group mapping服务,可得到该用户的属组,该服务由`hadoop.security.group.mapping`参数决定,默认情况下,该属性值为`org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback`,即若JNI可用,通过JNI调用api来获取属组信息,若JNI不可用,该属性值为`org.apache.hadoop.security.ShellBasedUnixGroupsMapping`,即linux下的属组。当然,该属性值也可设置为`org.apache.hadoop.security.LdapGroupsMapping`来通过LDAP来获取属组信息。 65 | 66 | 对于HDFS而言,**用户与属组的对应关系需在NameNode上体现**,即若希望指定用户的属组,需要在NN上做调整,若使用YARN,还需要在RM上做调整。 67 | 68 | 69 | ### 案例 70 | 通过flume写的文件,其文件属性为`drwxrwx--- - flume hive /user/hive/warehouse/test.db`,此时若通过ma用户来访问数据,会报Permission Denied的问题,即使添加acl后,test.db上新建的目录ma用户仍然无法访问。根据上面说明,可给test.db目录加default acl,或者在nn上将ma的属组调整为hive。 71 | 72 | 参考 73 | --- 74 | - [HDFS Permissions Guide](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html) 75 | - [HDFS ACLs: Fine-Grained Permissions for HDFS Files in Hadoop](http://zh.hortonworks.com/blog/hdfs-acls-fine-grained-permissions-hdfs-files-hadoop/) 76 | 77 | 78 | -------------------------------------------------------------------------------- /hadoop/hdfs/apt_install_hadoop_cdh.md: -------------------------------------------------------------------------------- 1 | Ubuntu 下使用apt安装单机cdh5 2 | === 3 | 4 | 在安装前确认java,javac等版本是否一致,如果不一致的话,参考[How To Install Java on Ubuntu with Apt-Get](https://www.digitalocean.com/community/tutorials/how-to-install-java-on-ubuntu-with-apt-get)重新安装。 5 | 6 | 参考[cloudera](http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_cdh5_install.html#topic_4_4_1_unique_2__p_44_unique_2) Ubuntu 安装Hadoop(CDH),步骤如下: 7 | 8 | - 下载 cloudera.list 9 | 10 | ``` 11 | sudo wget http://archive.cloudera.com/cdh5/ubuntu/precise/amd64/cdh/cloudera.list -O /etc/apt/sources.list.d/cloudera.list 12 | ``` 13 | 14 | - 添加key 15 | 16 | ``` 17 | $ wget http://archive.cloudera.com/cdh5/ubuntu/precise/amd64/cdh/archive.key -O archive.key 18 | $ sudo apt-key add archive.key 19 | ``` 20 | 21 | - 更新源, `sudo apt-get update` 22 | 23 | ``` 24 | sudo apt-get install hadoop-yarn-resourcemanager hadoop-hdfs-namenode hadoop-hdfs-secondarynamenode hadoop-hdfs-datanode hadoop-mapreduce hadoop-client hadoop-mapreduce-historyserver hadoop-yarn-proxyserver hadoop-client hadoop-0.20-mapreduce-jobtracker hadoop-0.20-mapreduce-tasktracker 25 | ``` 26 | - 修改配置 27 | 28 | /etc/hadoop/conf/core-site.xml 29 | ``` 30 | 31 | 32 | fs.defaultFS 33 | hdfs://localhost:9000 34 | 35 | 36 | hadoop.tmp.dir 37 | /home/hadoop/dfs 38 | 39 | 40 | ``` 41 | 42 | /etc/hadoop/conf/hdfs-site.xml 43 | ``` 44 | 45 | 46 | dfs.namenode.name.dir 47 | /home/hadoop/dfs/nn 48 | 49 | 50 | dfs.datanode.data.dir 51 | /home/hadoop/dfs/dn 52 | 53 | 54 | ``` 55 | 56 | /etc/hadoop/conf/mapred-site.xml 57 | ``` 58 | 59 | 60 | mapred.job.tracker 61 | localhost:9001 62 | 63 | 64 | ``` 65 | 66 | - 启动服务 67 | ``` 68 | sudo service hadoop-hdfs-namenode start 69 | sudo service hadoop-hdfs-datanode start 70 | sudo service hadoop-0.20-mapreduce-jobtracker start 71 | sudo service hadoop-0.20-mapreduce-tasktracker start 72 | ``` 73 | 74 | 安装完成。 75 | -------------------------------------------------------------------------------- /hadoop/hdfs/build_libhdfs_so.md: -------------------------------------------------------------------------------- 1 | # 编译生成 libhdfs.so 2 | 3 | git hadoop-hdfs 源码后。进入 `hadoop-hdfs/src`,然后执行 `cmake -DGENERATED_JAVAH=${JAVA_HOME} .`,然后执行 `make`,在 `target/usr/local/lib` 目录下可以看到生成的 libhdfs.so.0.0.0 文件。 4 | 5 | 然后将生成的 libhdfs.so.0.0.0 拷贝到 `$HADOOP_PREFIX/lib/native/` 目录中,再做个软链 libhdfs.so 指向该文件。 6 | -------------------------------------------------------------------------------- /hadoop/hdfs/compile_hadoop.md: -------------------------------------------------------------------------------- 1 | ## 编译 Hadoop 源码 2 | 3 | ### 准备 4 | - Unix/Linux OS 5 | - JDK 1.7+ 6 | - Maven 3.0+ 7 | - ProtocolBuffer 2.5.0 8 | 9 | 关于上述软件的安装这里略去,如需编译 native code,还需要 CMake 2.6+,Zlib-devel,Openssl-devel等,这里暂不考虑。 10 | 11 | ### 安装 Hadoop 12 | 下载源码并编译出二进制文件,执行命令如下: 13 | ``` 14 | # git clone git@github.com:apache/hadoop.git 15 | # cd hadoop 16 | # git check branch-2.7.3 17 | // 编译二进制文件 18 | # mvn package -Pdist -DskipTests -Dtar 19 | # cd hadoop-dist/target/hadoop-2.7.3 20 | // 查看 hdfs 版本 21 | # bin/hdfs version 22 | Hadoop 2.7.3 23 | Subversion https://github.com/apache/hadoop.git -r baa91f7c6bc9cb92be5982de4719c1c8af91ccff 24 | ``` 25 | 26 | 接着修改配置文件,其中 `etc/hadoop/core-site.xml` 修改如下: 27 | ``` 28 | 29 | 30 | fs.default.name 31 | hdfs://localhost:9000 32 | 33 | 34 | ``` 35 | 36 | `etc/hadoop/hdfs-site.xml` 修改如下: 37 | ``` 38 | 39 | 40 | dfs.replication 41 | 1 42 | 43 | 44 | ``` 45 | 接着给本用户登录本机设置免密码登录,使用 `ssh localhost` 进行验证。若成功,接下来执行如下步骤: 46 | ``` 47 | // 格式化 namenode 48 | # bin/hdfs namenode -format 49 | // 启动 hdfs 50 | # sbin/start-dfs.sh 51 | ``` 52 | 53 | 在浏览器中打开 http://localhost:50070, 即可看到 namenode web 页面,说明安装成功。 54 | 55 | ### 调试 Hadoop 56 | 57 | #### 设置hadoop-env.sh 58 | 在 IntelliJ IDEA 中打开 Hadoop 源码,点击 Run --> Edit Configurations --> Add New Configuration --> Remote,修改其名字为 NameNodeDebug,点击 Apply,如下图: 59 | 60 | ![debug_conf](../img/debug_hadoop_conf.png) 61 | 62 | 接着复制 Command line arguments for running remote JVM 的值:`-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005`,将其粘贴于 etc/hadoop/hadoop-env.sh 中,如下: 63 | 64 | ``` 65 | export HADOOP_NAMENODE_OPTS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005" 66 | export HADOOP_NAMENODE_OPTS="-Dhadoop.security.logger=${HADOOP_SECURITY_LOGGER:-INFO,RFAS} -Dhdfs.audit.logger=${HDFS_AUDIT_LOGGER:-INFO,NullAppender} $HADOOP_NAMENODE_OPTS" 67 | ``` 68 | 将 `suspend=n` 修改为 `suspend=y`,这样 hdfs 会挂起在任何 debug namenode 的地方。 69 | 70 | #### 挂起 NameNode 并在 5005 端口监听 71 | 重启 Hadoop: 72 | ``` 73 | # sbin/stop-dfs.sh 74 | # sbin/start-dfs.sh 75 | # jps 76 | 44932 SecondaryNameNode 77 | 44745 -- main class information unavailable 78 | 45275 Jps 79 | 44828 DataNode 80 | ``` 81 | 82 | 在启动过程中,如果看到 `localhost: Listening for transport dt_socket at address: 5005` 则说明调试模式下启动 namenode 成功。 83 | 84 | #### 设置断点 85 | 在 IntelliJ 中设置断点。 86 | 87 | #### 调试 88 | 打开 IntelliJ,点击 NameNodeDebug 旁边的 Debug 按钮,开始调试。如下图: 89 | 90 | ![debug](../img/debug_hadoop.png) 91 | 92 | 以上。 93 | 94 | ### 参考 95 | - [BUILDING.txt](https://github.com/apache/hadoop/blob/branch-2.7.3/BUILDING.txt) 96 | -------------------------------------------------------------------------------- /hadoop/hdfs/ha.md: -------------------------------------------------------------------------------- 1 | HDFS HA 2 | ==== 3 | 4 | 5 | 参考 6 | --- 7 | 8 | - [Administering an HDFS High Availability Cluster](http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_hag_hdfs_ha_admin.html#concept_ccf_cxf_vn_unique_1) 9 | - [A Guide to Checkpointing in Hadoop](http://blog.cloudera.com/blog/2014/03/a-guide-to-checkpointing-in-hadoop/) 10 | - [HDFS High Availability Using the Quorum Journal Manager](https://hadoop.apache.org/docs/r2.3.0/hadoop-yarn/hadoop-yarn-site/HDFSHighAvailabilityWithQJM.html) 11 | - [Quorum-based Journaling in CDH4.1](http://blog.cloudera.com/blog/2012/10/quorum-based-journaling-in-cdh4-1/) 12 | -------------------------------------------------------------------------------- /hadoop/hdfs/hdfs_guide.md: -------------------------------------------------------------------------------- 1 | HDFS 2 | === 3 | 4 | 这里记录下HDFS中一些容易混淆和一些需要注意的地方。 5 | 6 | Secondary NameNode, CheckPoint Node, Backup Node 和 Standby NameNode 的区别 7 | --- 8 | 9 | 在说这些节点区别时,先说下NameNode的启动过程: 10 | ### NameNode启动过程 11 | 12 | FSImage文件包含文件系统中所有目录、文件的序列化信息和数据块的映射信息,edits记录了集群所有的变更操作。当NameNode启动时,会加载fsimage和edits来生成一个新的fsimage,之后群集的变更都会更新到edits中。 13 | 14 | - Namenode 从FSImage中读取系统元数据 15 | - 读取Edits,将文件变更操作应用在文件系统的元数据上 16 | - 新写一个 checkpoint(即当前FSImage与Edits合并) 17 | - 进入安全模式,直到各datanode报告足够的block为止。([默认情况](https://hadoop.apache.org/docs/r2.3.0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml)下,datanode报告的block为元数据记录的block的0.999倍即退出安全模式) 18 | 19 | Hadoop中有几种提供CheckPoint的方法,如下。 20 | 21 | ### Secondary NameNode 22 | 随着edits的增加,当Namenode重启时,花费在合并edits与fsimage上的时间会很多,这是Secondary NameNode产生的原因。Secondary NameNode 并不是Hadoop HA的备用NanmeNode。在Hadoop2之前,它是唯一一个checkpoint进程。 23 | 24 | Secondary NameNode周期性检查NameNode的 fsimage 和 edits是否需要合并,如果需要合并的话,其先触发edit roll,然后下载NameNode中的fsimage和edits文件进行合并生成新的 fsimage,再将新的 fsimage 上传给 Namenode。Secondary NameNode通常和NameNode不是运行在一个节点上。Secondary的checkpoint进程由 `dfs.namenode.checkpoint.period` 和 `dfs.namenode.checkpoint.txns` 两个参数共同控制。过程如下: 25 | 26 | ![](../../img/secondarynn.png) 27 | 28 | 当需要使用Secondary NameNode恢复数据时,将其数据拷贝到NameNode即可。但Namenode中在snn做最后一次的checkpoint之后的edits需要重放。 29 | 30 | ### Checkpoint Node 31 | 因为Secondary NameNode 给人带来混淆,后面版本中使用Checkpoint Node 用来代替Secondary NameNode。其作用和配置和Secondary Namenode 一样。 32 | 33 | Checkpoint Node使用命令 `bin/hdfs namenode -checkpoint` 启动,Checkpoint 节点位置由`dfs.namenode.backup.address`和`dfs.namenode.backup.http-address`决定。Checkpoint Node 启动checkpoint的条件同snn触发条件。 34 | 35 | ### Backup Node 36 | Backup Node除了提供和Checkpoint Node一样的Checkpoint功能外,还从 NameNode 接收journal流文件形式的edits,并持久化到磁盘,同时将这些edits加载到内存中,这样便在内存中还维持了一份和当前Namenode *实时同步* 的文件系统命名空间(因此Backup Node内存应和Active Namenode大小一样)。因此当有Backup Node时,可以不需要使用Checkpoint node。Backup Node 不需要从Namenode下载fsimage和 edits,因此做checkpoint时效率比SNN或Checkpoint Node高很多。 37 | 38 | Backup Node的缺点:1)不具热备性:Namenode发生问题时,还需要手动重启NameNode。2)Backup Node没保存block的信息,若切到Backup Node做namenode,仍需要datanode上报各自block位置,因此,即使后续版本实现热备,切换仍需要时间。3)当前一个NameNode只支持一个Backup Node,未来可能会考虑支持多个Backup node。 39 | 40 | 启动Backup node的命令为`bin/hdfs namenode -backup`,Backup node节点位置由`dfs.namenode.backup.address`和`dfs.namenode.backup.http-address`决定。 41 | 42 | ### Standby Namenode 43 | 在HA结构中的任何时间点,保证只有一个active的namenode和一个standby的namenode,active namenode负责集群所有操作,standby仅做热备。namenode的切换通过ZKFC机制实现。每个namenode上均存在ZKFC进程,ZKFC通过心跳通信检测NameNode状态是否发生变化。 44 | 45 | 目前有两种实现形式的HA: 1) Journal Node。namenode将edits写到大多数(N/2+1)journal node节点中,standby 去读取这些edits并执行,这样使得active nn和standby nn的元数据处于同一状态。 2) NFS。active和standby对NFS有同样的权限, active namenode将edits写到NFS,然后standby去同步edits并执行,使用active nn和standby的元数据处于同一状态。这种方式对NFS设备要求较高,网络,磁盘,电源等都需要做冗余。 46 | 47 | Reference 48 | --- 49 | - [HdfsUserGuide](http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html#Secondary_NameNode) 50 | - [A Guide to Checkpointing in Hadoop](http://blog.cloudera.com/blog/2014/03/a-guide-to-checkpointing-in-hadoop/) 51 | - [High Availability for the Hadoop Distributed File System (HDFS)](http://blog.cloudera.com/blog/2012/03/high-availability-for-the-hadoop-distributed-file-system-hdfs/) 52 | - [HDFS High Availability Using the Quorum Journal Manager](http://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html) 53 | 54 | -------------------------------------------------------------------------------- /hadoop/hdfs/small_files.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - [Working with Small Files in Hadoop - Part 1](http://inquidia.com/news-and-info/working-small-files-hadoop-part-1) 4 | - [The Small Files Problem](http://blog.cloudera.com/blog/2009/02/the-small-files-problem/) 5 | -------------------------------------------------------------------------------- /hadoop/hdfs/sourcecode/README.md: -------------------------------------------------------------------------------- 1 | ## README 2 | 随着 Hadoop 使用程度的加深,对其原理理解的需求越来越迫切。另外在实际工作中,也会遇到通过查询源码来调优参数的情况。基于以上原因,这里对 Hadoop 源码做个探讨。 3 | 4 | - Hadoop Version: 2.7.3 5 | 6 | ### 目录 7 | - [Namenode](namenode.md) [TODO] 8 | - [Datanode](datanode.md) [TODO] 9 | - [Heartbeart](heartbeart.md) [TODO] 10 | - [RPC][rpc.md] [TODO] 11 | - [FSNameSystem](fsnamesystem.md) [TODO] 12 | - [磁盘异构] 13 | -------------------------------------------------------------------------------- /hadoop/hdfs/switch_namenode.md: -------------------------------------------------------------------------------- 1 | 集群Namenode切换方案 2 | ==== 3 | 4 | 环境:CDH4.5 5 | 目标:nn1(active), nn2(standby) --> nn1-alt(active), nn2(standby)。 6 | 7 | 过程 8 | --- 9 | *注:以下操作均在 Cloudera Manager 的HDFS页中完成。* 10 | 11 | 1. 备份HDFS, HIVE元数据。(脚本备份&&mysql停slave) 12 | 2. 配置NameService (30s) 13 | 在 HDFS 的 Configuration 中,搜索 `nameservice`, 修改`NameNode Nameservice` 和 `SecondaryNameNode Nameservice`的值,使两个值相同。 14 | 3. 停HA (4min) 15 | 在 HDFS 的 Instances 中,点击 `Federation and High Availability` 中的 `Actions` 按钮,选择 `Disable High Availability`,选择nn2为namenode,随机选择一个节点做SecondaryNameNode Host. 16 | *注:若依赖HDFS的部分组件重启失败,则需要手动重启,同时再发布下客户端的配置。* 17 | 4. 若节点A之前是JournalNode,第二次仍选其做JournalNode时,需备份之前JournalNode目录数据,并清空该目录。 18 | 5. 启用HA (6min) 19 | - 在 HDFS 的 Instaces 中,点出 Acitons 按钮,选择 `Enable High Availability` 20 | - 填写 Nameservice Name,为 nameservice1 21 | - 选择 NameNode Hosts,加上 nn1-alt, 并重新选择 JournalNode Hosts(这里选择和切换前一样多的JournalNode:3个),一直点击Continue,重启集群 22 | 若`Deploy Client Configuration`失败,则手动deploy. 23 | 6. 配置Hue 和 重启 Hive: 24 | - For each of the Hive service(s) Hive, stop the Hive service, back up the Hive Metastore Database to a persistent store, run the service command "Update Hive Metastore NameNodes", then restart the Hive services. 25 | 7. Manual Failover (2min) 26 | 在 HDFS 的 Instances 中,点击 `Federation and High Availability` 中的 `Actions` 按钮,选择 `Manual Failover`,选择 nn1-alt 为 namenode. 27 | 8. 检查 HDFS, HBase, Hive etc。 28 | 29 | 问题 30 | --- 31 | 32 | - JouralNode 目录清空 33 | 34 | 若切换前JouralNode在A,B,C三台机器上,切换过程中,指定B,C,D为新的JournalNode,则在启动HA时,需要先清空B,C上JournalNode目录中的数据。在CM5中,会帮助清除该目录,但CM4中需手动清除。 35 | 36 | - `/run`目录在被mount时去掉 `noexec` 属性。 37 | 38 | 新加入集群的NameNode机器报错如下: 39 | ``` 40 | java.io.IOException: Cannot run program "/run/cloudera-scm-agent/process/5695-hdfs-NAMENODE/topology.py" (in directory "/run/cloudera-scm-agent/process/5695-hdfs-NAMENODE"): java.io.IOException: error=13, Permission denied 41 | ``` 42 | 经发现,`/run`目录下的所有可执行文件都不能以`./script_name`执行(文件有可运行权限),经查明,`/run`目录被mount时,带有`noexec`,而CM4和对应Ubuntu有bug,导致`topology.py`无法运行,机架位置获取不到,产生这个问题。重新mount去掉该属性即可解决这个问题:`mount -o remount,exec /run`。 43 | 44 | 45 | -------------------------------------------------------------------------------- /hadoop/hdfs/trash.md: -------------------------------------------------------------------------------- 1 | Hadoop 的Trash功能 2 | === 3 | 4 | 目前hadoop 集群经常会报磁盘空间不足的报警,在CM里设置的`fs.trash.interval` 为10天,因此Trash中的文件很大。在和相关业务部门讨论后,确定trash中的部分数据可以立即删除,因此需要写脚本每天去检查trash中的这些文件并删除之。其实在写业务部门删除文件时,对于不需要放trash中的文件,可指定`-skipTrash`删除即可。 5 | 6 | 先说下trash的原理。当trash设置时间后,在 Hdfs 中删除文件时,Namenode并不会立即将文件或目录删除掉,而是先放在Trash中。每个用户有自己相应的Trash,路径为`/user/username/.Trash`。根据`fs.trash.interval`中设置的日期,NameNode会在每次相隔日期时(格林威治时间为0点,因此北京时间为早上8点)启动后台线程Emptier检查每个用户的`.Trash`目录是否有过期文件(yyMMddHHmmss形式的),若有则删除,然后将当前要删除的目录(即Current目录)重命名为yyMMddHHmmss(注意hadoop1.x中目录名为yyMMddHHmm,因此从1.x升级到2.x后,trash中的文件不会被删除),因此在 `/user/username/.Trash`目录,可以看到目录的保留时间在0~2*`fs.trash.interval`之间(因为先删除再保存的缘故)。 7 | 8 | trash目录和其它目录一样,只不过在从trash中删除时,不会将文件再放入trash,这时会真正的将文件删除。 9 | 10 | 对于我们的需要而言,需要写脚本去删除,因此使用`hdfs dfs -expunge` 或 `rm`去删除trash文件即可。 11 | -------------------------------------------------------------------------------- /hadoop/img/Copy_of_Yarn_mem_params.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/Copy_of_Yarn_mem_params.jpg -------------------------------------------------------------------------------- /hadoop/img/debug_hadoop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/debug_hadoop.png -------------------------------------------------------------------------------- /hadoop/img/debug_hadoop_conf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/debug_hadoop_conf.png -------------------------------------------------------------------------------- /hadoop/img/hdfs_recovery_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/hdfs_recovery_1.png -------------------------------------------------------------------------------- /hadoop/img/hdfs_recovery_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/hdfs_recovery_2.jpg -------------------------------------------------------------------------------- /hadoop/img/krbmsg.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/krbmsg.gif -------------------------------------------------------------------------------- /hadoop/img/rack_topology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/rack_topology.png -------------------------------------------------------------------------------- /hadoop/img/rebalance.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/rebalance.jpg -------------------------------------------------------------------------------- /hadoop/img/secondarynn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hadoop/img/secondarynn.png -------------------------------------------------------------------------------- /hadoop/mapreduce/join.md: -------------------------------------------------------------------------------- 1 | # MapReduce Join分析 2 | 3 | ## Reference 4 | - [MapReduce Algorithms - Understanding Data Joins Part 1](http://codingjunkie.net/mapreduce-reduce-joins/) 5 | -------------------------------------------------------------------------------- /hadoop/mapreduce/shuffle分析.md: -------------------------------------------------------------------------------- 1 | # Shuffle分析 2 | 3 | 4 | 5 | ## Reference 6 | - [MapReduce Internals](http://www.bigsynapse.com/mapreduce-internals) 7 | -------------------------------------------------------------------------------- /hbase/README.md: -------------------------------------------------------------------------------- 1 | ## HBase 文档 2 | 3 | _说明:若源码版本未特别指明,则默认为 1.2。_ 4 | 5 | ### 目录 6 | #### Chapter 1 Basic 7 | - [HBase Architecture](docs/hbase_architecture.md) :point_left: 8 | - [HBase WAL ](docs/hbase_wal.md) 9 | - [HBase MemStore](docs/hbase_memstore.md) 10 | - [HBase HFile](docs/hbase_hfile.md) 11 | - [HBase Compaction](docs/hbase_compaction.md) 12 | - [HBase Split](docs/hbase_split.md) 13 | - [HBase Merge](docs/hbase_merge.md) 14 | - [HBase Meta](docs/hbase_meta.md) 15 | - [HBase BlockCache](docs/hbase_blockcache.md) 16 | - [HBase Shell](docs/hbase_shell.md) 17 | - [Zookeeper](docs/hbase_zookeeper.md) 18 | 19 | #### Chapter 2 Advanced 20 | - [lsm](docs/lsm.md) 21 | - [HBase Write Path](docs/hbase_write_path.md) 22 | - [HBase Read Path](docs/hbase_read_path.md) 23 | - [HBase 二级索引](docs/hbase_secondary_index.md) 24 | - [HBase RPC分析](docs/hbase_rpc.md) 25 | - [HBase Filter](docs/hbase_filter.md) 26 | - [BloomFilter](docs/hbase_bloom_filter.md) 27 | - [Comprosser](docs/hbase_compressor.md) 28 | - [HBase 中的锁](docs/hbase_lock.md) 29 | - [HBase MVCC](docs/hbase_mvcc.md) 30 | - [HBase MTTR](docs/hbase_mttr.md) 31 | - [HBase Timeline Consistency](docs/hbase_timeline_consistency.md) 32 | - [HBase TimeOut](docs/hbase_timeout.md) 33 | - [HBase Retry](docs/hbase_retry.md) 34 | - [HBase Replication](docs/hbase_replication.md) 35 | 36 | #### Chapter 3 Usage 37 | - [Reading Data from HBase](docs/read_data_from_hbase.md) 38 | - [Writing Data to HBase](docs/write_data_to_hbase.md) 39 | - [Importing Data into HBase](docs/import_data_into_hbase.md) 40 | 41 | #### Chapter 4 Source Code 42 | - [Region In Transcation 分析](docs/hbase_sc_rit.md) 43 | - [RegionServer 分析](docs/hbase_sc_regionserver.md) 44 | - [Region 分析](docs/hbase_sc_region.md) 45 | - [Split 分析](docs/source_code/hbase_sc_split.md) 46 | - [ConnectionCache](docs/hbase_sc_connectioncache.md) 47 | 48 | #### Chapter 5 Tune 49 | - [安装 HBase](docs/hbase_install.md) 50 | - [HBase 优化](docs/https://github.com/mattshma/hbase/blob/master/src/main/asciidoc/_chapters/performance.adoc) 51 | - [hbase 配置](docs/hbase_conf.md) 52 | - 资源隔离 53 | - 权限 54 | 55 | #### Chapter 6 Other 56 | - [搭建HBase本地调试环境](docs/debug_hbase_source_code.md) 57 | 58 | #### Reference 59 | - [Apache HBase](https://blogs.apache.org/hbase/) 60 | - [Cloudera Blog -- HBase](http://blog.cloudera.com/blog/category/hbase/) 61 | - [有态度的 HBase](http://hbasefly.com/) 62 | 63 | 64 | -------------------------------------------------------------------------------- /hbase/docs/debug_hbase_source_code.md: -------------------------------------------------------------------------------- 1 | # 编译 HBase 源码 2 | 3 | 由于本人使用的HBase 版本为 1.2,所以这里以 branch-1.2 做为例子,其他版本类推。IDE 为 IntelliJ IDEA。 4 | 5 | ## HBase-server 6 | 过程如下: 7 | ``` 8 | > git clone git@github.com:apache/hbase.git 9 | > cd hbase 10 | # 切换到1.2分支 11 | > git checkout branch-1.2 12 | > mvn clean install -DskipTests 13 | ``` 14 | 1.2 版本默认对应的 Hadoop 版本为 2.5.1,若需要修改为其他版本,可使用命令: `mvn clean install -Denforcer.skip=true -Dhadoop-two.version=2.7.2 -DskipTests -Prelease`。编译完成后,接着在 IntelliJ 中导入源码:选择 File --> New --> Project From Existing Sources...,选择hbase导入。导入后,选择 Edit Configurations,如下图: 15 | 16 | ![hbase_edit_configuration](../img/build_hbase_edit_con.jpg) 17 | 18 | 接着新建 Application,如下: 19 | 20 | ![hbase_new_application](../img/build_hbase_new_application.jpg) 21 | 22 | 配置 Application: 23 | 24 | ![hbase_run_conf](../img/build_hbase_conf_conf.jpg) 25 | 26 | 配置 Applicaiton Name 为 HMaster(任意名),设置 Main class 为`org.apache.hadoop.hbase.master.HMaster`,Program arguments 为 `start`,VM options 设置下log, 为 `-Dlog4j.configuration=file://hbase/conf/log4j.properties`。点击 Apply 和 OK。 27 | 28 | 设置Application后,点击运行即可。 运行HMaster,端口为16010,而非60010。在浏览器中输入 http://localhost:16010 ,即可看到页面如下: 29 | 30 | ![hbase_run](../img/build_hbase_run.jpg) 31 | 32 | 若启动过程HMaster过程中报错如下: 33 | ``` 34 | java.lang.RuntimeException: hbase-default.xml file seems to be for an older version of HBase (@@@VERSION@@@), this version is 1.2.5-SNAPSHOT 35 | at org.apache.hadoop.hbase.HBaseConfiguration.checkDefaultsVersion(HBaseConfiguration.java:71) 36 | at org.apache.hadoop.hbase.HBaseConfiguration.addHbaseResources(HBaseConfiguration.java:81) 37 | at org.apache.hadoop.hbase.HBaseConfiguration.create(HBaseConfiguration.java:96) 38 | at org.apache.hadoop.hbase.util.ServerCommandLine.doMain(ServerCommandLine.java:126) 39 | at org.apache.hadoop.hbase.master.HMaster.main(HMaster.java:2485) 40 | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 41 | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 42 | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 43 | at java.lang.reflect.Method.invoke(Method.java:606) 44 | at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 45 | ``` 46 | 47 | 则先将 hbase/hbase-common/src/main/resource/hbase-default.xml 中的 `hbase.defaults.for.version.skip` 属性设置为 `true`,然后再启动即可。 48 | 49 | ## HBase Shell 50 | 启动 HMaser,接下来编译 HBase Shell。点击 Edit Configurations...,新建Application,在 Name 栏写:HBaseShell(或其他),Main class 填 `org.jruby.Main`, Program arguments 填 hbase/bin/hirb.rb,根据 hbase/bin/hirb.rb,知其需要传递参数 `hbase.ruby.sources`,因此 VM options 填 `-Dhbase.ruby.sources=//hbase/hbase-shell/src/main/ruby`。如下图: 51 | 52 | ![hbase_shell](../img/build_hbase_shell.jpg) 53 | 54 | 点击 Apply 和 OK。 55 | 56 | 运行 HBaseShell,即可输入相关 hbase shell 命令,如下图: 57 | 58 | ![hbase_run_shell](../img/build_hbase_run_shell.jpg) 59 | 60 | 61 | ## 参考 62 | - [Building and Developing Apache HBase](https://github.com/apache/hbase/blob/7294931e622e6e8f4b3a9e88acba84d837660c16/src/main/asciidoc/_chapters/developer.adoc#build) 63 | - [How-to: Create an IntelliJ IDEA Project for Apache Hadoop](http://blog.cloudera.com/blog/2014/06/how-to-create-an-intellij-idea-project-for-apache-hadoop/) 64 | - [PHOENIX-1411](https://issues.apache.org/jira/browse/PHOENIX-1411) 65 | 66 | -------------------------------------------------------------------------------- /hbase/docs/hbase_architecture.md: -------------------------------------------------------------------------------- 1 | # HBase Architecture 2 | 3 | ## Overview 4 | HBase 有如下特性: 5 | 6 | - 强一致性 7 | - 自动分片 8 | - RegionServer 自动故障转移 9 | - 整合 Hadoop/HDFS 10 | - 支持 MapReduce 11 | - 提供 Java Client API 12 | - 提供 Thrift/REST API 13 | - Block Cache 和 Bloom Filter 14 | - 便于管理 15 | 16 | ## HBase 的一致性 17 | > [CAP定理](https://zh.wikipedia.org/wiki/CAP%E5%AE%9A%E7%90%86)指出对于一个分布式系统而言,不可能同时满足以下三点: 18 | - 一致性(Consistence) 19 | - 可用性(Availability) 20 | - 网络分区容忍性(Partition tolerance) 21 | > 22 | > 对于分布式系统而言,分区容忍性是基本要求,所以在设计分布式数据系统时,需要在一致性和可用性中做权衡,但无论如何做权衡,都无法完全放弃一致性,如果真的放弃一致性,那么这个系统中的数据就变得不可信了。一般而言,分布式数据系统会牺牲部分一致性,使用最终一致性。 23 | > 24 | > 常见的一致性类型有: 25 | > - 强一致性:当更新操作完成后,之后任意进程任何时间的请求的返回值都是一致的。 26 | > - 弱一致性:更新完成后,系统并不保证后续请求的返回值是一致的(更新前和更新后的值都可能被返回),也不保证过多久返回的值一致。 27 | > - 最终一致性:更新完成后,在“不一致窗口”后的请求的返回值都是一致。最终一致性是弱一致性的特例。 28 | > 29 | 30 | ### HBase 有哪几种一致性? 31 | - 强一致性(Strong Consistency) 32 | 强一致性是 HBase 的默认一致性模型。 33 | - 时间轴一致性(Timeline Consistency) 34 | 时间轴一致性的读请求的返回结果可能不包括最近更新的数据,即 get 和 scan 可能包括过期数据。为保证写事务的顺序,HBase 中的写事务都是强一致性模型。 若需要使用时间轴一致性的读请求,可执行命令:`get 't1','r6', {CONSISTENCY => "TIMELINE"}`。 35 | 36 | ### HBase 是怎样保证强一致性的呢? 37 | - 每个值只出现在一个 region。 38 | - 同一时间每个 region 只被分配给一个 region server。 39 | - 所有行内的 mutation 操作都是原子操作。 40 | - 通过任何 API 返回的行的内容总是一个完整的行。 41 | 42 | ## Architecture 43 | 引用的一张图: 44 | 45 | ![hbase_arch](../img/hbase_arch.png) 46 | 47 | 每个 HRegionServer 共享一个WAL,HRegionServer 有一个或多个 Region 构成,每个 Region 下又有一个或多个 Store,每个表的列族对应一个 Store 实例,每个 Store 包括一个或多个 StoreFile 实例,StoreFile 为 HBase 实际存储文件 HFile 的封装,每个 Store 对应一个 MemStore。HFile 由多个 Block 组成。 48 | 49 | ``` 50 | Table (HBase table) 51 | Region (Regions for the table) 52 | Store (Store per ColumnFamily for each Region for the table) 53 | MemStore (MemStore for each Store for each Region for the table) 54 | StoreFile (StoreFiles for each Store for each Region for the table) 55 | Block (Blocks within a StoreFile within a Store for each Region for the table) 56 | ``` 57 | 58 | ## LSM树 & B+树 --> TODO 59 | 60 | ## Reference 61 | - [Apache HBase ™ Reference Guide](https://hbase.apache.org/book.html) 62 | - [Consistency](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Consistency.html) 63 | - [HBase: How does replication work](http://stackoverflow.com/questions/5417574/hbase-how-does-replication-work) 64 | - [HBase Read Replicas](http://www.cloudera.com/documentation/enterprise/5-4-x/topics/admin_hbase_read_replicas.html) 65 | - [HBase Read High Availability Using Timeline Consistent Region Replicas](http://www.slideshare.net/enissoz/hbase-high-availability-for-reads-with-time) 66 | - [What are HBase znodes](http://blog.cloudera.com/blog/2013/10/what-are-hbase-znodes/) 67 | -------------------------------------------------------------------------------- /hbase/docs/hbase_bloomfilter.md: -------------------------------------------------------------------------------- 1 | ## BloomFilter 2 | 3 | 4 | BloomFilter适用于Get操作,对于Scan没有效果。[passesBloomFilter](https://github.com/apache/hbase/blob/496fd9837a0fb199a516758a632fecfe59b0b480/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreFileReader.java#L247)如下: 5 | ``` 6 | /** 7 | * Checks whether the given scan passes the Bloom filter (if present). Only 8 | * checks Bloom filters for single-row or single-row-column scans. Bloom 9 | * filter checking for multi-gets is implemented as part of the store 10 | * scanner system (see {@link StoreFileScanner#seekExactly}) and uses 11 | * the lower-level API {@link #passesGeneralRowBloomFilter(byte[], int, int)} 12 | * and {@link #passesGeneralRowColBloomFilter(Cell)}. 13 | * 14 | * @param scan the scan specification. Used to determine the row, and to 15 | * check whether this is a single-row ("get") scan. 16 | * @param columns the set of columns. Only used for row-column Bloom 17 | * filters. 18 | * @return true if the scan with the given column set passes the Bloom 19 | * filter, or if the Bloom filter is not applicable for the scan. 20 | * False if the Bloom filter is applicable and the scan fails it. 21 | */ 22 | boolean passesBloomFilter(Scan scan, final SortedSet columns) { 23 | // Multi-column non-get scans will use Bloom filters through the 24 | // lower-level API function that this function calls. 25 | if (!scan.isGetScan()) { 26 | return true; 27 | } 28 | 29 | byte[] row = scan.getStartRow(); 30 | switch (this.bloomFilterType) { 31 | case ROW: 32 | return passesGeneralRowBloomFilter(row, 0, row.length); 33 | 34 | case ROWCOL: 35 | if (columns != null && columns.size() == 1) { 36 | ... 37 | return passesGeneralRowColBloomFilter(kvKey); 38 | } 39 | 40 | // For multi-column queries the Bloom filter is checked from the 41 | // seekExact operation. 42 | return true; 43 | 44 | default: 45 | return true; 46 | } 47 | } 48 | ``` 49 | 50 | 51 | 52 | ### Reference 53 | - [How are bloom filters used in HBase](https://www.quora.com/How-are-bloom-filters-used-in-HBase) 54 | -------------------------------------------------------------------------------- /hbase/docs/hbase_column_family_options.md: -------------------------------------------------------------------------------- 1 | HBase 建表时的一些参数分析 2 | === 3 | 4 | 对于HBase而言,选择合适的参数如同关系型数据库中选择引擎或CHAR vs VARHCAR vs TEXT 一样重要,这些参数对数据存取改删等都有影响。 5 | 6 | compression 7 | --- 8 | 9 | 默认情况下 HBase 不对数据进行压缩,但实际上有两种压缩方式:BLOCK,RECORD 10 | 11 | ### Block compression 12 | 13 | 如果 HBase 表中某列的值是一个很大的文本数据, 14 | 15 | 参考 16 | --- 17 | 18 | - [Understanding HBase column-family performance options](http://jimbojw.com/wiki/index.php?title=Understanding_HBase_column-family_performance_options) 19 | - [Appendix E. Compression and Data Block Encoding In HBase](http://hbase.apache.org/book/compression.html) 20 | 21 | -------------------------------------------------------------------------------- /hbase/docs/hbase_compaction.md: -------------------------------------------------------------------------------- 1 | # HBase Compaction 2 | 3 | memstore flush会生成很多文件,如果这些文件达到阈值,会触发这些文件的compaction操作以减少文件数目,这个过程一直持续到这些文件中最大的文件超过配置的HRegion大小,然后会触发split操作。 4 | 5 | compaction分为minor和major两种。minor只是将小文件合并成一个大文件,不删除数据。major会对region下的所有storeFile执行合并操作并最终生成一个文件。 6 | 7 | ## minor compaction 8 | 9 | 如下参数会影响minor compaction: 10 | 11 | - hbase.hstore.compaction.min 12 | 每个Store中需要compaction的StoreFile数目的最小值,默认值为3。调优该值的目标是避免过多太小的StoreFiles进行compact。若其值设置为2,每次一个Store有2个StoreFile都会触发一次minor compaction,这并不太合适。若该值设置太大,需要其他影响minor compaction的值也设置合理。对于大多数情况而言,默认值都能满足。 13 | - hbase.hstore.compaction.max 14 | 触发单个minor compaction的最大StoreFile数。 15 | - hbase.hstore.compaction.min.size 16 | 小于该值的StoreFile自动做为需要minor compaction的StoreFile。该值默认同`hbase.hregion.memstore.flush.size`,即128Mb。对于写压力较大的场景,该值可能需要调小。因为这种使用场景中小文件非常多,即使StoreFile做了minor compaction后,新生成文件的大小仍小于该值。 17 | - hbase.hstore.compaction.max.size 18 | 大于该值的StoreFile自动从minor compaction中排除。该值默认为9223372036854775807 byte,即`LONG.MAX_VALUE`。 19 | - hbase.hstore.compaction.ratio 20 | 对于minor compaction而言,该值能判断大于`hbase.hstore.compaction.min.size`的StoreFile是否会被compaction,将StoreFile按年龄排序,若该文件的大小小于minor compaction后生成文件的大小乘以该ratio的话,则该文件也就做minor compaction,minor compatcion总是从老文件开始选择。如ratio为1,文件从老到新大小依次为100,50, 23, 12 和 12 字节,`hbase.hstore.compaction.min.size`为10,由于`100>(50+23+12+12)*1`和`50>(23+12+12)*1`,所以100,50不会被compaction,而由于`23<(12+12)*0.1`,所以23及比其小的12(文件个数须小于hbase.hstore.compaction.max)均应被compaction。该值是浮点数,默认为1.2。 21 | - hbase.hstore.compaction.ratio.offpeak 22 | 低峰期时可设置不同的ratio用以让大尺寸的StoreFile进行compaction,方法同`hbase.hstore.compaction.ratio`,该值仅当`hbase.offpeak.start.hour`和`hbase.offpeak.end.hour`开启时才生效。 23 | 24 | ## major compaction 25 | major compaction会合并Region下所有StoreFile最终生成一个文件。触发major compaction的条件有:major_compact、majorCompact() API、RegionServer自动运行。影响RegionServer自动运行的相关参数如下: 26 | 27 | - hbase.hregion.majorcompaction 28 | 每次执行major compaction的时间间隔,默认为7天。若设置为0,即禁止基于时间的major compaction。若major compaction对影响较大,可将该值设为0,通过crontab或其他文件来执行major compaction。 29 | 30 | - hbase.hregion.majorcompaction.jitter 31 | 为防止同一时间运行多个major compaction,该属性对`hbase.hregion.majorcompaction`规定的时间进行了浮动,该值默认值为0.5,即默认情况下major compaction时间在[7-7*0.5天, 7+7+0.5天]这个范围内。 32 | 33 | ## 参考 34 | - [hbase-default.xml](https://github.com/apache/hbase/blob/master/hbase-common/src/main/resources/hbase-default.xml) 35 | - [Regions](http://hbase.apache.org/0.94/book/regions.arch.html) 36 | -------------------------------------------------------------------------------- /hbase/docs/hbase_conf.md: -------------------------------------------------------------------------------- 1 | # HBase Configuration 2 | 目前在做 HBase Client 相关的一些工作,由于涉及到 client 端的一些优化,这里整理一版脱水版的配置,做全局查看用。 3 | 4 | HBase Version: 1.2.x 5 | 6 | ## hbase-default.xml 默认配置 7 | 8 | ### Client configurations 9 | 10 | name | value | description 11 | -----------------------|-------------------------|----------------------- 12 | hbase.client.write.buffer | 2097152 | client write buffer 的 bytes 大小。 server 端需要实例化 client 传过来的 write buffer,所以较大的 write buffer 同时在 client 和 server 端占用更多内存,server 端占用内存为 `hbase.client.write.buffer` * `hbase.regionserver.handler.count`。 13 | hbase.client.pause | 100 | client 暂停时间因子,单位为 ms,与 [RETRY_BACKOFF](https://github.com/apache/hbase/blob/branch-1.2/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java#L583) 相乘的积为重试间隔时间。 14 | hbase.client.retries.number | 35 | 最大重试次数。见 RETRY_BACKOFF 。 15 | hbase.client.max.total.tasks | 100 | 单个 HTable 实例可以提交的最大并发任务数。 16 | 17 | 18 | ## 参考 19 | - [hbase-default.xml](https://github.com/apache/hbase/blob/branch-1.2/hbase-common/src/main/resources/hbase-default.xml) 20 | - [hbase-default.adoc](https://github.com/apache/hbase/blob/branch-1.2/src/main/asciidoc/_chapters/hbase-default.adoc) 21 | -------------------------------------------------------------------------------- /hbase/docs/hbase_filter.md: -------------------------------------------------------------------------------- 1 | # HBase Filter 2 | 在使用scan和get从HBase中读取数据时,可以通过filter来减少返回给客户端的数据量。 3 | 4 | 通过filter的[Class Hierarchy](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/package-tree.html),可以看到所有的比较器都继承自`FilterBase`。以下针对几个比较器进行说明。 5 | 6 | ## CompareFilter 7 | [CompareFilter](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/CompareFilter.html)提供了基于行,qualifier,value等的比较,其主要由比较符(operator)和比较器(comparator)两部分构成。 8 | 9 | CompareFilter有如下几类: 10 | - DependentColumnFilter 11 | - FamilyFilter 12 | - QualifierFilter 13 | - RowFilter 14 | - ValueFilter 15 | 16 | 其中[比较符](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/CompareFilter.CompareOp.html)有如下类别: 17 | 18 | - EQUAL 19 | 相等。 20 | - GREATER 21 | 大于。 22 | - GREATER_OR_EQUAL 23 | 大于等于。 24 | - LESS 25 | 小于。 26 | - LESS_OR_EQUAL 27 | 小于等于。 28 | - NO_OP 29 | 无操作符。 30 | - NOT_EQUAL 31 | 不相等。 32 | 33 | 34 | 而[比较器](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/ByteArrayComparable.html)有如下几种: 35 | 36 | - BinaryComparator 37 | 比较两个字节数组。 38 | - BinaryPrefixComparator 39 | 匹配字节数组的指定前缀。 40 | - BitComparator 41 | 指定的字节数组执行指定的位操作,判断返回结果是否为0。 42 | - LongComparator 43 | 指定的long值与字节数组比较。 44 | - NullComparator 45 | 是否为空。 46 | - RegexStringComparator 47 | 正则比较。 48 | - SubstringComparator 49 | 子字符串比较。 50 | 51 | 52 | 以下举例说明: 53 | ``` 54 | hbase(main):013:0* import org.apache.hadoop.hbase.filter.RowFilter 55 | => Java::OrgApacheHadoopHbaseFilter::RowFilter 56 | hbase(main):015:0* import org.apache.hadoop.hbase.filter.CompareFilter 57 | => Java::OrgApacheHadoopHbaseFilter::CompareFilter 58 | hbase(main):017:0* import org.apache.hadoop.hbase.filter.SubstringComparator 59 | => Java::OrgApacheHadoopHbaseFilter::SubstringComparator 60 | hbase(main):018:0> import org.apache.hadoop.hbase.filter.BinaryComparator 61 | => Java::OrgApacheHadoopHbaseFilter::BinaryComparator 62 | hbase(main):034:0> scan 'game_role', {LIMIT => 5, FILTER => RowFilter.new(CompareFilter::CompareOp::EQUAL, SubstringComparator.new('0000e3y1darrvtmdevsnsrccihtt0c_51006001'))} 63 | ``` 64 | ## 参考 65 | - [org.apache.hadoop.hbase.filter](https://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/package-summary.html) 66 | - [HBase Filtering](https://www.cloudera.com/documentation/enterprise/latest/topics/admin_hbase_filtering.html) 67 | -------------------------------------------------------------------------------- /hbase/docs/hbase_hfile.md: -------------------------------------------------------------------------------- 1 | # HBase HFile 分析 2 | 3 | 网上查了下, 4 | 5 | 6 | ## 工具 7 | $ ${HBASE_HOME}/bin/hbase org.apache.hadoop.hbase.io.hfile.HFile 8 | usage: HFile [-a] [-b] [-e] [-f ] [-k] [-m] [-p] [-r ] [-v] 9 | -a,--checkfamily Enable family check 10 | -b,--printblocks Print block index meta data 11 | -e,--printkey Print keys 12 | -f,--file File to scan. Pass full-path; e.g. 13 | hdfs://a:9000/hbase/.META./12/34 14 | -k,--checkrow Enable row order check; looks for out-of-order keys 15 | -m,--printmeta Print meta data of file 16 | -p,--printkv Print key/value pairs 17 | -r,--region Region to scan. Pass region name; e.g. '.META.,,1' 18 | -v,--verbose Verbose output; emits file and meta data delimiters 19 | 20 | 21 | ## 参考 22 | - [HFile format](http://hbase.apache.org/1.2/book.html#_hfile_format_2) 23 | - [Apache HBase I/O – HFile](http://blog.cloudera.com/blog/2012/06/hbase-io-hfile-input-output/) 24 | - [HFile.java](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFile.java) 25 | - [HBASE-11729](https://issues.apache.org/jira/browse/HBASE-11729) 26 | -------------------------------------------------------------------------------- /hbase/docs/hbase_memstore.md: -------------------------------------------------------------------------------- 1 | # HBase MemStore分析 2 | 3 | ## MemStore Flush 4 | 5 | - hbase.hregion.memstore.flush.size 6 | 单个memstore能达到的上限值(默认为128M)。当memstore达到该值时,会触发memstore的flush操作,此时的flush不阻塞写操作。每隔`hbase.server.thread.wakefrequency`(默认值为10s)检查一次。 7 | 8 | - hbase.hregion.memstore.block.multiplier 9 | 当一个region的memstore总量达到 `hbase.hregion.memstore.block.multiplier`(默认值为2) * `hbase.hregion.memstore.flush.size`时,会触发memstore的flush操作,并阻塞这个region的写操作。这种情况只发生在即将写满2*128M时再写入一个大对象时发生。 10 | 11 | - hbase.regionserver.global.memstore.lowerLimit/upperLimit 12 | 一个RS可能会有多个Region,每个Region有多个memstore,所以可能单个Region没超过阈值,但整个RegionServer占用的内存已经非常多了,这时还有`hbase.regionserver.global.memstore.lowerLimit`和`hbase.regionserver.global.memstore.upperLimit`来控制memstore的flush。当RegionServer上所有memstore占用的大小达到RegionServer Java Heap的`hbase.regionserver.global.memstore.lowerLimit`(默认值为0.35)倍时,会选择一些占用内存比较大的memstore强制flush并阻塞这些memstore的写操作;若RegionServer所有memstore占用的内存大小达到RegionServer Java Heap的`hbase.regionserver.global.memstore.upperLimit`(默认为0.4)倍时,会阻塞该regionserver所有写操作并触发将rs所有memstore的flush操作。 13 | 14 | - hbase.regionserver.maxlogs 15 | WAL文件的数量的最大值,默认为32。由于数据通过WAL写入Memstore,当WAL大小达到`hbase.regionserver.maxlogs` * `hbase.regionserver.hlog.blocksize`(CDH中为HDFS的配置dfs.blocksize)时,为减小其大小,需要将memstore中数据flush到HLog,然后才能将这部分WALs删除。 16 | 17 | - hbase.regionserver.optionalcacheflushinterval 18 | 为避免所有memstore在同一时间进行flush操作,会对memstore定期进行flush,默认时间为1小时。 19 | 20 | - 手动flush 21 | 22 | 在hbase shell中,可针对某个表或某个Region进行flush。 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /hbase/docs/hbase_meta.md: -------------------------------------------------------------------------------- 1 | # hbase:meta表简介 2 | 3 | ## hbase:meta介绍 4 | 在0.96之前的版本中,hbase的meta信息通过-ROOT-表来查询,在0.96.0之后的版本中,移除了-ROOT-表,.meta.被重重命名为hbase:meta,并且其位置存储在zookeeper中。 5 | 6 | ``` 7 | # hbase shell 8 | > scan 'hbase:meta', LIMIT=>1 9 | TestTable,00000000000000000000183519,14 column=info:regioninfo, timestamp=1457515420191, value={ENCODED => fbc3f12f6e05daa4ec0b17e431c4f509, NAME => 'TestTab 10 | 57515419490.fbc3f12f6e05daa4ec0b17e431c le,00000000000000000000183519,1457515419490.fbc3f12f6e05daa4ec0b17e431c4f509.', STARTKEY => '000000000000000000001835 11 | 4f509. 19', ENDKEY => '00000000000000000000367087'} 12 | TestTable,00000000000000000000183519,14 column=info:seqnumDuringOpen, timestamp=1461725865195, value=\x00\x00\x00\x00\x00\x00\x03\x1E 13 | 57515419490.fbc3f12f6e05daa4ec0b17e431c 14 | 4f509. 15 | TestTable,00000000000000000000183519,14 column=info:server, timestamp=1461725865195, value=10-2-96-43:60020 16 | 57515419490.fbc3f12f6e05daa4ec0b17e431c 17 | 4f509. 18 | TestTable,00000000000000000000183519,14 column=info:serverstartcode, timestamp=1461725865195, value=1461665925512 19 | 57515419490.fbc3f12f6e05daa4ec0b17e431c 20 | 4f509. 21 | ``` 22 | 23 | rowkey即为每个Region的Name,rowkey的格式为:`tableName,regionStartKey,regionId.encodedRegionName`,regionId通常是[region创建的时间点](https://hbase.apache.org/apidocs/src-html/org/apache/hadoop/hbase/HRegionInfo.html#line.375)。encodedRegionName是对RegionName中`.`前部分(即`tableName,regionStartKey,regionId`)的md5 hash。根据rowkey可以找到相应region在hdfs中的位置:`/////`。fileName是基于Java内建的随机数生成器产生的任意数字。 24 | 25 | 每个rowkey在info列族有[如下列](https://github.com/apache/hbase/blob/master/hbase-client/src/main/java/org/apache/hadoop/hbase/MetaTableAccessor.java): 26 | 27 | >info:regioninfo => contains serialized HRI for the default region replica 28 | info:server => contains hostname:port (in string form) for the server hosting 29 | the default regionInfo replica 30 | info:server_ => contains hostname:port (in string form) for the server hosting the 31 | regionInfo replica with replicaId 32 | info:serverstartcode => contains server start code (in binary long form) for the server 33 | hosting the default regionInfo replica 34 | info:serverstartcode_ => contains server start code (in binary long form) for the 35 | server hosting the regionInfo replica with replicaId 36 | info:seqnumDuringOpen => contains seqNum (in binary long form) for the region at the time 37 | the server opened the region with default replicaId 38 | info:seqnumDuringOpen_ => contains seqNum (in binary long form) for the region at 39 | the time the server opened the region with replicaId 40 | info:splitA => contains a serialized HRI for the first daughter region if the 41 | region is split 42 | info:splitB => contains a serialized HRI for the second daughter region if the 43 | region is split 44 | info:mergeA => contains a serialized HRI for the first parent region if the 45 | region is the result of a merge 46 | info:mergeB => contains a serialized HRI for the second parent region if the 47 | region is the result of a merge 48 | > 49 | 50 | 一般而言,在`hbase:meta`表中,正常的region会有`info:regioninfo`、`info:server`、`info:serverstartcode`等列,`info:regioninfo` 51 | 52 | info:regioninfo等如何产生?为什么只有reioninfo信息没其他信息。 53 | 54 | 如何修复? 55 | 56 | ## zookeeper 57 | 58 | 59 | ## 参考 60 | - [What are HBase znodes](http://blog.cloudera.com/blog/2013/10/what-are-hbase-znodes/) 61 | - [hbase-meta](https://github.com/XingCloud/HMitosis/wiki/hbase-meta) 62 | -------------------------------------------------------------------------------- /hbase/docs/hbase_mttr.md: -------------------------------------------------------------------------------- 1 | # HBase MTTR 2 | HBase 通过每个值只出现在一个 Region,同一时间每个 Region 只被分配给一个 RegionServer 来保证一致性。如果 RegionServer 实例挂掉或者服务器宕机,怎样尽量检查异常并恢复对 Offline Region 的访问,是 MTTR (MEAN TIME TO RECOVERY) 需要考虑的事。 3 | 4 | 众所周知,HBase 将数据保存在 HFile 中,而 HFile 存储在 HDFS 上,默认会被复制 2 份,即备份数为3。另外 HBase 使用的 WAL 也存储在 HDFS 中,备份数也为3。所以即使两台机器宕机,HBase也能恢复Region。 5 | 6 | ## HBase错误检测和恢复 7 | HBase错误检测和恢复过程如下: 8 | 9 | - 检测节点失败。 10 | 节点可能因为压力过大或者机器宕机而停止响应。 11 | - 恢复正在进行的写操作。 12 | 通过读取 WAL 和恢复还未 flush 的 edits 进行恢复。 13 | - 重新分配 Regions。 14 | 根据各存活的 RegionServer 的压力随机分配 Regions。 15 | 16 | 以上过程中,在检测和恢复动作发生之前,客户端因 RegionServer 宕掉一直处于阻塞状态。怎样减少客户端对数据停机的感知时间,即怎样缩减检测节点失败和恢复 Region 的时间,是 MTTR 需要做的。 17 | 18 | ### 检测节点失败 19 | RegionServer失败的原因有好几种,第一种情况是服务被正常关闭,如服务被管理员关闭。对于这种情况,RegionServer 关闭 Region 后会通知 HMaster 其正在关闭,清除 WAL,接着 HMaster 立即分配 Region。第二种情况是网络异常或服务器异常等异常情况。对于这种情况, RegionServer 无法给 HMaster 发送信息,由于每个 RegionServer 都连接 Zookeeper 保持心跳信息,所以这种情况下如果 HMatser 监测某 RegionServer 的心跳 timeout,HMaster 将会宣布其死亡,然后开启恢复进程。 20 | 21 | ### 恢复正在进行的写操作 22 | 由于每个 RegionServer 共用一个 WAL 文件,而 WAL 中包括各个 Region 相关的文件,所在在恢复时,WAL 需按 Region 进行切分,异常 RegionServer 上的 Region 被分配到随机的 RegionServer 上,这些 RegionServer 读取切分后的 WAL 进行恢复。上面说过,WAL 在 HDFS 也保存了 3 份。所以在读取 WAL 进行恢复的过程中,WAL 的 block 有 33% 的机率会被指向异常 RegionServer 所在的 DataNode。这就说如果异常 RegionServer 所在机器的 DataNode 能正常访问,则立即进行恢复。若异常 RegionServer 所在机器的 DataNode 不能访问,此时只能等待请求返回 timeout 后,去尝试请求另一个 DataNode 的 block。这种情况延长了恢复时间。 23 | 24 | ### 重新分配 Regions 25 | 一旦完成恢复写操作后,重新分配 Region 会很快执行,该操作依赖 Zookeeper,参见[HBASE-7247](https://issues.apache.org/jira/browse/HBASE-7247)。更多 Assignment 过程可参考[HBASE-7327](https://issues.apache.org/jira/browse/HBASE-7327)。 26 | 27 | ## MTTR 调优分析 28 | 从以上分析可以看出,若 RegionServer 被正常关闭,Region 的恢复相当快速。但若 RegionServer 因网络异常或机器宕机等意外情况无法访问,在检测阶段和恢复阶段,将花费大量时间在请求等待 timeout 上,因此优化的思路也很明确 -- 尽量减少检测和恢复的 timeout 时间。 29 | 30 | 对于检测失败节点,timeout 时间由 `zookeeper.session.timeout` 设置,默认值为 90s。为减少检测失败节点时间,可适当降低该值,不过由于 RegionServer GC 也会导致无法向 Zookeeper 发送心跳,因此该值需大于 RegionServer GC 时间。 31 | 32 | 对于恢复正在进行的写操作,由于需要恢复 WAL,最坏情况是找到仅存的一个 block(即2个RegionServer挂掉),所以如果 HBase 的 timeout 时间为 60s 的话,则 HDFS 需设置为 20s 无响应的话即认为 DataNode 挂掉。在 HDFS 中,若一个 DataNode 被宣告死亡,则其复本需复制到其他存活的 DataNode 上,显然,这个操作是很消耗资源的。如果多个 DataNode 同时被宣告死亡,将引发"replication storms": 大量复本都需要复制,导致系统过载,部分节点压力过大,无法发送心跳信息,进而这些节点被宣告死亡,这又导致这些节点上的复本需要复制,依此循环。基于这个原因,HDFS 在启动恢复进程前会先等待一段时间(大于10分钟),对于 HBase 这样的低延迟系统,显然这是无法接受的。在 [HDFS 1.2](https://issues.apache.org/jira/browse/HDFS-3912) 的版本后,引入了一个特殊状态:`stale` -- 若在指定时间内 HDFS 节点没发送心跳信息,则标记该节点状态为 stale。该状态的节点不能接收写请求,对于读请求,也是优先选择非 stale 的节点。在 [hdfs-site.xml](https://github.com/apache/hadoop/blob/branch-2.8.0/hadoop-hdfs-project/hadoop-hdfs/src/main/resources/hdfs-default.xml) 中,设置 stale 的配置如下: 33 | 34 | ``` 35 | 36 | dfs.namenode.avoid.read.stale.datanode 37 | true 38 | 39 | 40 | 41 | dfs.namenode.avoid.write.stale.datanode 42 | true 43 | 44 | 45 | 46 | dfs.namenode.write.stale.datanode.ratio 47 | 1.0f 48 | 49 | When the ratio of number stale datanodes to total datanodes marked 50 | is greater than this ratio, stop avoiding writing to stale nodes so 51 | as to prevent causing hotspots. 52 | 53 | 54 | ``` 55 | 56 | 通过上面配置,Region 恢复将只与 HBase 有关。 57 | 58 | ## 参考 59 | - [INTRODUCTION TO HBASE MEAN TIME TO RECOVERY (MTTR)](http://hortonworks.com/blog/introduction-to-hbase-mean-time-to-recover-mttr/) 60 | - [HBASE-5843](https://issues.apache.org/jira/browse/HBASE-5843) 61 | 62 | -------------------------------------------------------------------------------- /hbase/docs/hbase_mvcc.md: -------------------------------------------------------------------------------- 1 | ## MVCC 2 | 3 | ### Reference 4 | - [Apache HBase Internals: Locking and Multiversion Concurrency Control](https://blogs.apache.org/hbase/entry/apache_hbase_internals_locking_and) 5 | -------------------------------------------------------------------------------- /hbase/docs/hbase_replication.md: -------------------------------------------------------------------------------- 1 | # HBase Replication 2 | 3 | 需要注意的几点: 4 | - 保证源集群和目标集群时间一致(建表使用 NTP 同步) 5 | 源集群中如下几种情况数据不会复制到目标集群: 6 | - 开启复制前源集群中已存在的数据。 7 | - 由于复制是通过 WAL 进行的,所以如果源集群中操作跳过 WAL 的话,则这些操作对应的数据也不会同步到目标集群,如 BulkLoad 或设置 writeToWal(false) 的 API 调用。 8 | - 表结构修改。 9 | 10 | zk结构。 11 | 12 | read/filter/ship 13 | 14 | 15 | 何时会复制: 16 | By default, a source will try to read from a log file and ship log entries as fast as possible to a sink. This is first limited by the filtering of log entries; only KeyValues that are scoped GLOBAL and that don't belong to catalog tables will be retained. A second limit is imposed on the total size of the list of edits to replicate per slave, which by default is 64MB. This means that a master cluster RS with 3 slaves will use at most 192MB to store data to replicate. This doesn't account the data filtered that wasn't garbage collected. 17 | 18 | 19 | 20 | The edit is then tagged with the master's cluster UUID. When the buffer is filled, or the reader hits the end of the file, the buffer is sent to a random region server on the slave cluster. 21 | 22 | ## Q 23 | 1. 数据啥时候传输呢?从上看文件会立即传输,但有两个限制:1. only KeyValues that are scoped GLOBAL and that don't belong to catalog tables will be retained。 2. Once the maximum size of edits was buffered or the reader hits the end of the log file, the source thread will stop reading and will choose at random a sink to replicate to. buffer 默认大小为64M,即若读到 HLOG 末尾或 buffer 满了,会开始复制。这样数据量小的会在读到hlog尾时开始复制。 24 | 25 | [64M](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/ReplicationSource.java#L165) 26 | 27 | 内部 28 | 29 | 注意点: 30 | 31 | 默认复制因子为 [0.1](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/replication/regionserver/ReplicationSinkManager.java#L57) 32 | 33 | KEEP_DELETED_CELLS=true 34 | 35 | 目前replication 对于压缩的hlog的wal entry 无法解析?:http://blog.csdn.net/teriy/article/details/7968181 36 | 37 | Replication_scope 能设置为2.。 If set REPLICATION_SCOPE to 2, we will push edits by the order of written.? 38 | 39 | 40 | HLog Compression/Replication compatibility: HBase Replication is now compatible with HLog compression. This means a cluster with WAL compression can replicate its data to another cluster with no WAL compression, and vice versa. (See for details: HBASE-5778.) 41 | 42 | 43 | status 'replication'参数说明. 44 | 45 | ## 参考 46 | - [HBase Cluster Replication](http://hbase.apache.org/book.html#_cluster_replication) 47 | - [HBase 0.94 replication overview](https://hbase.apache.org/0.94/replication.html) 48 | - [HBase Replication](https://www.cloudera.com/documentation/enterprise/5-8-x/topics/cdh_bdr_hbase_replication.html#topic_20_11) 49 | - [HBASE-17460](https://issues.apache.org/jira/browse/HBASE-17460) 50 | - [HBASE-9531](https://issues.apache.org/jira/browse/HBASE-9531) 51 | - [HBASE-5778](https://issues.apache.org/jira/browse/HBASE-5778) 52 | -------------------------------------------------------------------------------- /hbase/docs/hbase_retry.md: -------------------------------------------------------------------------------- 1 | # HBase Retry 2 | 3 | ## BACKOFF 4 | 5 | [HConstants.java](https://github.com/apache/hbase/blob/branch-1.2/hbase-common/src/main/java/org/apache/hadoop/hbase/HConstants.java#L575) 中 `public static final int [] RETRY_BACKOFF = {1, 2, 3, 5, 10, 20, 40, 100, 100, 100, 100, 200, 200};` 6 | 7 | [ConnectionUtils.java](https://github.com/apache/hbase/blob/branch-1.2/hbase-client/src/main/java/org/apache/hadoop/hbase/client/ConnectionUtils.java#L52)中 getPauseTime 如下: 8 | ``` 9 | public static long getPauseTime(final long pause, final int tries) { 10 | int ntries = tries; 11 | if (ntries >= HConstants.RETRY_BACKOFF.length) { 12 | ntries = HConstants.RETRY_BACKOFF.length - 1; 13 | } 14 | if (ntries < 0) { 15 | ntries = 0; 16 | } 17 | 18 | long normalPause = pause * HConstants.RETRY_BACKOFF[ntries]; 19 | long jitter = (long)(normalPause * RANDOM.nextFloat() * 0.01f); // 1% possible jitter 20 | return normalPause + jitter; 21 | } 22 | ``` 23 | -------------------------------------------------------------------------------- /hbase/docs/hbase_rit.md: -------------------------------------------------------------------------------- 1 | # HBase Region in Transaction分析 2 | 3 | 4 | 5 | 6 | ![region_state](https://issues.apache.org/jira/secure/attachment/12668875/region_states.png) 7 | 8 | 9 | ## 参考 10 | - [HBASE-11961](https://issues.apache.org/jira/browse/HBASE-11961) 11 | - [Hbase Master RIT(Region in Transaction)分析](http://blog.csdn.net/teriy/article/details/6894303) 12 | - [Apache HBase AssignmentManager Improvements](http://blog.cloudera.com/blog/2012/11/apache-hbase-assignmentmanager-improvements/) 13 | -------------------------------------------------------------------------------- /hbase/docs/hbase_secondary_index.md: -------------------------------------------------------------------------------- 1 | # HBase Secondary Index 2 | 3 | HBase做为KV型数据库,Rowkey的设计十分重要,好的Rowkey需在查询条件和响应速度两方面满足业务需求。但在实际过程中,无论如何设计Rowkey,也可能出现单一Rowkey无法满足需求的情况,因此HBase引入二级索引的呼声也一直很高。 4 | 5 | ## Rowkey的设计原则 6 | 7 | 8 | 9 | 业务表Sample如下: 10 | 11 | RowKey | CF(info) 12 | -----------------|------------------------------------------------------- 13 | aid-bid-datetime | info:aid | info:bid | info:cid | info:did 14 | 15 | 16 | ## 二级索引方案 17 | 顾名思义,二级索引即在要查询的字段与一级索引建立一种映射关系。根据映射关系的存入位置,有如下两种方案。 18 | 19 | ### 表索引 20 | 使用单独的HBase表存储映射关系,查询条件组成一个Rowkey,Value即为对应的一级索引。对于表Sample,现在需通过cid-did 查询表中的数据,可建立索引表Index,该表Rowkey为 cid-did,value为表Sample中对应的aid-bid-datetime。 21 | 22 | ### 列索引 23 | 列索引即将索引列建在业务表上。为避免带来副作用,需要在逻辑上和物理上将索引数据与业务数据区分开。为提高性能,最好将索引数据与业务数据放在同一个Region中,此后查找一级Rowkey直接在Region进行,而不再需要全表扫描。通过合理的设计Rowkey前缀,可将索引数据全排在业务数据前面,这样做到了数据的逻辑区分。由于Region由一个或多个Store文件组成,每个Store只存储一个列族,因此索引列单独使用一个列族,可在物理上隔离索引数据与业务数据。 24 | 25 | 这里还是以Sample表为例,说下Rowkey的设计,首先建表时指定分区[0000, 0099], [0100, 0199]...[9900, 9999],这样有100个分区,对于业务数据的rowkey,格式为四位hash前缀-aid-bid。各rowkey的hash前缀值为其所在region起始值外的其他任意值,如对于region1,其hash前缀为[0001, 0099],其余依此类推。对于索引数据,rowkey格式曾四位hash前缀-查询条件代码-查询条件值-aid-bid,四位hash值为各region的起始值,如0000。若分别查询cid=01, did=02,其rowkey可以为0000-cid|bid-01|02-aa-02,查看aid=aa,cid=03,did=05,则rowkey为0000-aid|cid|did-aa|03|05-aa-03。 26 | 27 | 28 | 29 | ## 实现 30 | 31 | ### Phoenix 32 | 33 | 参考[Phoenix Secondary Indexing](https://phoenix.apache.org/secondary_indexing.html) 34 | 35 | ### Lily 36 | 37 | 从上可以看到,无论哪种设计,很重要的一点是将索引数据与业务放在同一个RegionServer甚至更细的粒度(如Region)。 38 | 39 | ## 参考 40 | - [HBase Rowkey Design](http://archive.cloudera.com/cdh5/cdh/5/hbase-1.0.0-cdh5.6.0/book.html#rowkey.design) 41 | - [Secondary Indexes and Alternate Query Paths](http://hbase.apache.org/book.html#secondary.indexes) 42 | - [HBase高性能复杂条件查询引擎](http://www.infoq.com/cn/articles/hbase-second-index-engine) 43 | - [Secondary Indexing In HBase: A tale of how to screw up a simple idea by breaking all the rules](https://www.linkedin.com/pulse/secondary-indexing-hbase-tale-how-screw-up-simple-idea-michael-segel?articleId=7019091741337614180#comments-7019091741337614180&trk=sushi_topic_posts) 44 | -------------------------------------------------------------------------------- /hbase/docs/hbase_timeline_consistency.md: -------------------------------------------------------------------------------- 1 | # HBase Timeline Consistency 2 | 3 | 在 MTTR 中提到 RegionServer 异常情况下的优化措施,不过对于部分场景,相比花很长时间获取正常数据而言,其也接收获取过期数据的情况。对于这种场景,HBase提供 Read Replics 方案。 4 | 5 | ## HBase Read Replicas 6 | Read Replicas,顾名思义即读可以多备份。开启 Read Replicas 后,除了某 RegionServer 拥有的默认 Region 外,HMaster 将多个只读 Region Replica 发送给不同的 RegionServer,默认 Region Replica 称为 **primary** replica,只读 Region Replicas 被称为 **secondaries** replica。secondary replicas 周期性的(由参数`hbase.regionserver.storefile.refresh.period`设置)读取 primary replica 的 HFile或通过复制(参数`hbase.region.replica.replication.enabled`设置)来更新数据,显然,若选择周期性更新的话,对于 primary replica 中 memstore 的数据,secondary regions 将暂时无法更新。所有拥有 replica 的region 都能处理读请求,不过 secondary regions 返回的数据会被标记为 "stale",客户端能检测数据是否为 "stale";另外,只有 primary region 能处理写请求。 7 | 8 | Region Replicas 尽可能的分布在不同机架上的不同机器中来保证高可用,一旦某机器宕机,可选择另外一台机器进行 GET 或 SCAN 操作,读取的数据可能是过期数据,这部分数据的取舍由用户端自行选择。 9 | 10 | 11 | ## Timeline Consistency 12 | HBase 默认一致性策略为 Strong Consistency,即读写请求只发送给相应的一个 Region。另外 HBase 还提供 Timeline Consistency 策略,即发送请求给所有拥有指定数据的 Region Replicas -- 读请求会先发送给 primary region,如果 `hbase.client.primaryCallTimeout.get` (默认为10ms) 时间内未收到 primary replica 的应答,再并发的将读请求发送给所有 secondary replicas。通过 Result.isStale() 能知道响应信息是否为 primary replica 返回。如果响应信息由 primary replica 返回,则数据为最新数据。 13 | 14 | ### 优缺点 15 | 16 | 优点: 17 | - 只读表的高可用 18 | - 过期数据读的高可用 19 | - 对于 99.9% 的读取过期数据的请求保持低延迟 20 | 21 | 缺点: 22 | - 多份 MemStore 空间占用 23 | - 占用 BlockCache 的使用 24 | - 复制 HFile 时会产生额外的网络开销 25 | - 若 primary replicas 响应不及时,会产生额外的 RPC 开销。 26 | 27 | 关于 Timeline Consistency 的更多信息,可参考 [官方文档](https://github.com/apache/hbase/blob/master/src/main/asciidoc/_chapters/architecture.adoc#102-timeline-consistency)。 28 | 29 | ## Read Replicas 配置 30 | 31 | ### 服务端配置 32 | 如下: 33 | 34 | 属性 | 设置值 | 说明 35 | --------|------------|---------- 36 | hbase.region.replica.replication.enabled | true | 若设置为 true,将通过复制来保证各 replicas 的数据同步,此时CF 上的 `REGION_MEMSTORE_REPLICATION`必须设置为 false。 37 | hbase.region.replica.replication.memstore.enabled | true | 38 | hbase.regionserver.storefile.refresh.period | 0 (disabled) | 通过拷贝 primary replica 的 HFile 来保证数据同步。如果周期设置过短,会加重 Namenode 的负担,若周期设置过长,sencondary replicas 的数据与 primary replica 的数据同步会不太及时。 39 | hbase.regionserver.meta.storefile.refresh.period | 300000ms | `hbase:meta` 表 sencondary replicas 同步 primary replica 的频率。 40 | hbase.master.hfilecleaner.ttl | 3600000ms | 41 | hbase.meta.replica.count | 3 | 42 | hbase.region.replica.storefile.refresh.memstore.multiplier | 4 | 43 | hbase.region.replica.wait.for.primary.flush | true | 44 | hbase.master.loadbalancer.class | org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer | 读取 sencondary replicas 时的负载均衡以平摊请求。 45 | 46 | 47 | ### 客户端配置 48 | 如下: 49 | 50 | 属性 | 设置值 | 说明 51 | --------|--------|----------- 52 | hbase.ipc.client.specificThreadForWriting | true | HBase 1.0.x 版本使用 `hbase.ipc.client.specificThreadForWriting` 而非该参数。 53 | hbase.client.primaryCallTimeout.get | 10ms | 54 | hbase.client.primaryCallTimeout.multiget | 10ms | 55 | hbase.client.replicaCallTimeout.scan | 10ms | 56 | hbase.meta.replicas.use | true | 57 | 58 | ### 激活 Read Replicas 59 | 60 | 建表时指定`REGION_REPLICATION`即可,如`hbase> create 'myTable', 'myCF', {REGION_REPLICATION => '3'}`。 61 | 62 | ## 参考 63 | - [Timeline-consistent High Available Reads](https://github.com/apache/hbase/blob/master/src/main/asciidoc/_chapters/architecture.adoc#10-timeline-consistent-high-available-reads) 64 | - [HBase Read Replicas](https://www.cloudera.com/documentation/enterprise/5-4-x/topics/admin_hbase_read_replicas.html) 65 | - [HBASE-10070](https://issues.apache.org/jira/browse/HBASE-10070) 66 | - [HBASE-10525](https://issues.apache.org/jira/browse/HBASE-10525) 67 | -------------------------------------------------------------------------------- /hbase/docs/hbase_timeout.md: -------------------------------------------------------------------------------- 1 | # HBase Timeout 2 | 3 | -------------------------------------------------------------------------------- /hbase/docs/hbase_tune.md: -------------------------------------------------------------------------------- 1 | 推荐配置 2 | --- 3 | ## ZooKeeper Configuration 4 | - zookeeper.session.timeout 5 | 暂时不优化该项 6 | - Number of ZooKeeper Instances 7 | 8 | ## RPC Handler 9 | 10 | - hbase.regionserver.handler.count 11 | 设置每个Region Server上的RPC handler数量。 12 | 13 | 参考 14 | --- 15 | - [Recommended Configurations](http://hbase.apache.org/book.html#recommended_configurations) 16 | -------------------------------------------------------------------------------- /hbase/docs/hbase_wal.md: -------------------------------------------------------------------------------- 1 | # WAL 2 | 3 | 为了避免服务器掉电丢失 Memstore 的数据,数据最先写入的是 WAL,然后才是 Memstore。WAL 的角色类似 Mysql 中的 Binlog,在 Memstore 数据丢失时,可用 WAL 来恢复数据。 4 | 5 | ## 概览 6 | 首先从直观上看下 WAL 相关信息。在 HDFS 上,关于 WAL 至少有两个目录:/hbase/WALs 和 /hbase/oldWALs。每个 RegionServer 在启动时都会分配一个由 host, port 和 startcode 组成的唯一标志,每个 RegionServer 对应一个 WAL,即每个 RegionServer 在 /hbase/WALs 中都有自己一个目录,该目录名由 host,port,stratcode 组成。整个 /hbase/WALs 目录下文件名组成为`/hbase/WALs/hostname,port,startcode/hostname%2Cport%2Cstartcode.timestamp`。 7 | 8 | 随着数据的不断写入,WAL 越来越大,当文件大小达到`hbase.regionserver.logroll.multiplier * hbase.regionserver.hlog.blocksize`时,会发生 WAL 滚动操作,其中`hbase.regionserver.logroll.multiplier`默认值为`0.95`,`hbase.regionserver.hlog.blocksize`大小默认为 HDFS 中`dfs.blocksize`大小,为 128M。另外,HBase 后台有一个 LogRoller 线程每隔`hbase.regionserver.logroll.period`(默认值为1小时)时间滚动 WAL,即使 WAL 大小小于阈值。当 RegionServer 下 WAL 文件数达到一定数目(默认为32,参见[源码](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/FSHLog.java#L522))时,会触发 Memstore 的 Flush 操作,对于已写入 HFile 的数据,其对应的 WAL 文件会被移到 /hbase/oldWALs 目录。 9 | 10 | ## WAL 剖析 11 | 查看 [WAL源码](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WAL.java#L50),知其由 Entry 构成,Entry 是 WAL 的最小存储单位。Entry 由 WALEdit 和 WALKey 构成,以下分别说下这两块内容。 12 | 13 | ### WALKey 14 | 查看 [WALKey](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALKey.java),其主要属性有: 15 | 16 | - encodedRegionName 17 | Entry 对应的 Region。 18 | - tablename 19 | Entry 对应的表名。 20 | - logSeqNum 21 | Entry 的序列号。 22 | - now 23 | edit 的写入时间。 24 | - clusterIds 25 | Replication 时需要传输 WAL 的集群。 26 | - mvcc 27 | 使用 mvcc 生成 writeEntry。 28 | 29 | ### WALEdit 30 | 每个 WALEdit 代表一个事务的 edit(KeyValue 对象)集合,每个 put 或 delete 操作都会封装成一个 WALEdit 实例。 查看 [WALEdit](docs/https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/WALEdit.java),其主要属性有: 31 | 32 | - METAFAMILY 33 | - METAROW 34 | - COMPACTION 35 | - FLUSH 36 | - REGION_EVENT 37 | - BULK_LOAD 38 | - isReplay 39 | 40 | 根据上述属性,可创建 FlushWALEdit, RegionEventWALEdit, Compaction 等不同的 WALEdit。 41 | 42 | ### FSHLog 43 | [FSHLog](https://github.com/apache/hbase/blob/branch-1.2/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/wal/FSHLog.java#L522) 是 WAL 的实现类,其主要实现了 append() 和 sync() 方法,并引入 [LMAX Disrutpor RingBuffer](https://github.com/LMAX-Exchange/disruptor/wiki/Introduction) ,实现内部 SyncRunner 线程刷写文件到磁盘中。 44 | 45 | 46 | 47 | 48 | ## 参考 49 | - [WAL](https://hbase.apache.org/book.html#wal) 50 | - [Apache HBase Write Path](http://blog.cloudera.com/blog/2012/06/hbase-write-path/) 51 | - [Hbase WAL 线程模型源码分析](https://www.qcloud.com/community/article/164816001481011969) 52 | -------------------------------------------------------------------------------- /hbase/docs/lsm.md: -------------------------------------------------------------------------------- 1 | # LSM 分析 2 | 3 | 4 | ## 参考 5 | - [The Log-Structured Merge-Tree (LSM-Tree)](http://www.cs.umb.edu/~poneil/lsmtree.pdf) 6 | - [Log Structured Merge Trees](http://www.benstopford.com/2015/02/14/log-structured-merge-trees/) 7 | - [日志结构的合并树 The Log-Structured Merge-Tree](http://www.cnblogs.com/siegfang/archive/2013/01/12/lsm-tree.html) 8 | 9 | -------------------------------------------------------------------------------- /hbase/img/ObjectLifetime.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/ObjectLifetime.gif -------------------------------------------------------------------------------- /hbase/img/build_hbase_conf_conf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_conf_conf.jpg -------------------------------------------------------------------------------- /hbase/img/build_hbase_edit_con.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_edit_con.jpg -------------------------------------------------------------------------------- /hbase/img/build_hbase_new_application.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_new_application.jpg -------------------------------------------------------------------------------- /hbase/img/build_hbase_run.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_run.jpg -------------------------------------------------------------------------------- /hbase/img/build_hbase_run_shell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_run_shell.jpg -------------------------------------------------------------------------------- /hbase/img/build_hbase_shell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/build_hbase_shell.jpg -------------------------------------------------------------------------------- /hbase/img/cms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/cms.png -------------------------------------------------------------------------------- /hbase/img/deletion_with_compact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/deletion_with_compact.png -------------------------------------------------------------------------------- /hbase/img/gc_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_1.png -------------------------------------------------------------------------------- /hbase/img/gc_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_2.png -------------------------------------------------------------------------------- /hbase/img/gc_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_3.png -------------------------------------------------------------------------------- /hbase/img/gc_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_4.png -------------------------------------------------------------------------------- /hbase/img/gc_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_5.png -------------------------------------------------------------------------------- /hbase/img/gc_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_6.png -------------------------------------------------------------------------------- /hbase/img/gc_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_7.png -------------------------------------------------------------------------------- /hbase/img/gc_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/gc_8.png -------------------------------------------------------------------------------- /hbase/img/hbase_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/hbase_arch.png -------------------------------------------------------------------------------- /hbase/img/hbase_protocal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/hbase_protocal.jpg -------------------------------------------------------------------------------- /hbase/img/hotspot_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/hotspot_heap.png -------------------------------------------------------------------------------- /hbase/img/hotspot_jvm_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/hotspot_jvm_architecture.png -------------------------------------------------------------------------------- /hbase/img/marking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/marking.png -------------------------------------------------------------------------------- /hbase/img/merge_region_networkio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/merge_region_networkio.png -------------------------------------------------------------------------------- /hbase/img/merge_region_num.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/merge_region_num.png -------------------------------------------------------------------------------- /hbase/img/normal_deletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/hbase/img/normal_deletion.png -------------------------------------------------------------------------------- /hbase/thrift2_demo/README.md: -------------------------------------------------------------------------------- 1 | HBase Thrift2 Python Demo 2 | --- 3 | 通过thrift2(python)访问HBase。 4 | 5 | TODO 6 | === 7 | - 多线程 8 | - 随机字符串 9 | 10 | 安装Thrift 11 | === 12 | 13 | 下载[thrift](http://thrift.apache.org/)后,安装即可。然后 14 | 15 | ``` 16 | # mkdir hbase_thrift2 17 | # cd hbase_thrift2 18 | # thrift --gen py /opt/cloudera/parcels/CDH/lib/hbase/include/thrift/hbase2.thrift 19 | # pip install hbase-thrift 20 | ``` 21 | 22 | 问题 23 | === 24 | 25 | - ImportError: cannot import name THBaseService 26 | 使用`from hbase import THBaseService`报错,修改为如下: 27 | ``` 28 | sys.path.append(os.path.abspath('gen-py/hbase')) 29 | from THBaseService import Client, TColumnValue, TPut, TGet 30 | ``` 31 | 即可。 32 | 33 | 参考 34 | === 35 | - [ThriftApi](https://wiki.apache.org/hadoop/Hbase/ThriftApi) 36 | - [DemoClient.py](https://github.com/apache/hbase/blob/master/hbase-examples/src/main/python/thrift2/DemoClient.py) 37 | -------------------------------------------------------------------------------- /hive/hive_add_jars.md: -------------------------------------------------------------------------------- 1 | # Hive 添加 jar 的方法 2 | 3 | 在 Hive 中经常遇到需要添加辅助(或第三方)jar 包的情况。这里简单记录下几种方法。 4 | 5 | - hive-cli 设置 --auxpath 6 | 这种方法是最通用的方法。不过在使用过程中,jar 包最好使用绝对路径,否则可能会报`Wrong FS: file://...expected: file:///`的问题。虽然 [HIVE-7531](https://issues.apache.org/jira/browse/HIVE-7531) 已经解决了相对路径的问题的,但实际仍有可能报这个错误。 7 | - ADD JAR 命令 8 | 进入 hive 后,使用 ADD JAR 添加 jar 包,这种方法适用于添加自定义的 UDF jar。 9 | - 设置 hive.aux.jars.path 10 | 该参数可以 hive-site.xml 中进行设置,或进入 hive 后使用 SET 设置。设置值为 jars 的路径。 11 | - 设置 HIVE_AUX_JARS_PATH 12 | 在 hive-env.sh 中设置该变量。 13 | 14 | ## 参考 15 | - [How to add auxiliary Jars in Hive](http://chetnachaudhari.github.io/2016-02-16/how-to-add-auxiliary-jars-in-hive/) 16 | - [HIVE-7531](https://issues.apache.org/jira/browse/HIVE-7531) 17 | -------------------------------------------------------------------------------- /hive/hive_cli.md: -------------------------------------------------------------------------------- 1 | # Hive client相关 2 | 3 | - 显示数据库 4 | 若要长久设置的话,在hive-site.xml中添加如下行: 5 | ``` 6 | 7 | hive.cli.print.current.db 8 | true 9 | 10 | ``` 11 | 若临时设置下,只需要在hive CLI中设置`set hive.cli.print.current.db=true;`。 12 | 13 | - 执行shell命令 14 | 15 | 在hive CLI中,只需在shell命令前加`!`即可执行。 16 | 17 | - 执行dfs命令 18 | 19 | 在hive CLI中,若希望执行dfs命令,只需将hdfs省略即可,如`dfs -ls /`。 20 | 21 | 22 | -------------------------------------------------------------------------------- /hive/hive_compile.md: -------------------------------------------------------------------------------- 1 | 参考 2 | - [Hive SQL的编译过程](http://tech.meituan.com/hive-sql-to-mapreduce.html) 3 | -------------------------------------------------------------------------------- /hive/hive_intro.md: -------------------------------------------------------------------------------- 1 | # Hive Intro 2 | 3 | ## Architecture 4 | 官网。 5 | 6 | ## File Formats 7 | 官网。 8 | 9 | - Avro 10 | - ORC 11 | - Parquet 12 | - Compressed Data Storage 13 | - LZO Compression 14 | 15 | ## Join 16 | 17 | ## Reference 18 | - [Design](https://cwiki.apache.org/confluence/display/Hive/Design) 19 | - [LanguageManual](https://cwiki.apache.org/confluence/display/Hive/LanguageManual) 20 | -------------------------------------------------------------------------------- /hive/hive压缩测试.md: -------------------------------------------------------------------------------- 1 | # Hive压缩 2 | 3 | 由于机房机柜不够,需要迁移Hadoop集群,查看集群文件,发现最大的几个目录都是Hive写入的。查看这些hive表结构,未使用压缩。为减少迁移数据量,先测试下能否先压缩几个大目录的hive数据。考虑到几点压缩格式的特点,这里使用lzo做为压缩格式。 4 | 5 | ## 目的 6 | - Hive表结构未定义压缩,若直接压缩HDFS中的文件,Hive是否还能正常读取这些文件?怎样验证压缩后文件的正确性? 7 | - 压缩前后读写速度对比。 8 | - 怎么更快的传输压缩数据? 9 | 10 | ## 准备 11 | 12 | ## 过程 13 | 14 | ### 压缩后文件是否不能使用? 15 | 压缩后,Hadop会根据文件扩展名推断使用哪个codec读取,所以理论上是可以读取的。 16 | 17 | 18 | -------------------------------------------------------------------------------- /hive/note.md: -------------------------------------------------------------------------------- 1 | # notes 2 | 3 | - `CREATE TABLE . LIKE .` 4 | 拷贝``的表结构到表``。 5 | - `CREATE TABLE . AS SELECT * FROM .` 6 | 拷贝``的表结构和数据到``。 7 | -------------------------------------------------------------------------------- /hive/乱码.md: -------------------------------------------------------------------------------- 1 | ## Hive show create table乱码问题 2 | 3 | ### 注释为中文时无法创建表 4 | 5 | 如下: 6 | ``` 7 | hive (test)> create table t1(id int comment '测试'); 8 | FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:javax.jdo.JDODataStoreException: Add request failed : INSERT INTO `COLUMNS_V2` (`CD_ID`,`COMMENT`,`COLUMN_NAME`,`TYPE_NAME`,`INTEGER_IDX`) VALUES (?,?,?,?,?) 9 | ``` 10 | 11 | 登录mysql,进入metastore库,如下: 12 | ``` 13 | mysql> show create table COLUMNS_V2\G 14 | *************************** 1. row *************************** 15 | Table: COLUMNS_V2 16 | Create Table: CREATE TABLE `columns_v2` ( 17 | `CD_ID` bigint(20) NOT NULL, 18 | `COMMENT` varchar(256) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL, 19 | `COLUMN_NAME` varchar(128) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, 20 | `TYPE_NAME` varchar(4000) CHARACTER SET latin1 DEFAULT NULL, 21 | `INTEGER_IDX` int(11) NOT NULL, 22 | PRIMARY KEY (`CD_ID`,`COLUMN_NAME`), 23 | KEY `COLUMNS_V2_N49` (`CD_ID`), 24 | CONSTRAINT `COLUMNS_V2_FK1` FOREIGN KEY (`CD_ID`) REFERENCES `cds` (`CD_ID`) 25 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 26 | 1 row in set (0.00 sec) 27 | 28 | # 修改字段注释字符集 29 | mysql> alter table COLUMNS_V2 modify COMMENT varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci; 30 | Query OK, 50263 rows affected (0.69 sec) 31 | 32 | # 修改表注释字符集 33 | mysql> alter table TABLE_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8; 34 | Query OK, 13340 rows affected (0.25 sec) 35 | 36 | # 修改分区注释字符集 37 | mysql> alter table PARTITION_KEYS modify column PKEY_COMMENT varchar(4000) character set utf8; 38 | Query OK, 4039 rows affected (0.09 sec) 39 | ``` 40 | 41 | 再次建表,成功。 42 | 43 | ### show create table显示注释乱码 44 | 45 | `desc table`正常,但`show create table`仍然是乱码。 46 | 47 | 48 | ### 参考 49 | - [HIVE-11837](https://issues.apache.org/jira/browse/HIVE-11837) 50 | 51 | 52 | -------------------------------------------------------------------------------- /java/IntelliJIDEA_ReferenceCard_Mac.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/IntelliJIDEA_ReferenceCard_Mac.pdf -------------------------------------------------------------------------------- /java/README.md: -------------------------------------------------------------------------------- 1 | 关于java的笔记。 2 | 3 | ## Basic 4 | - [JVM简介](jvm.md) 5 | - [Jav类的加载、链接及初始化](classloader.md) 6 | - [动态代理](dynamicProxy.md) 7 | - [Java与unix的I/O模型](java_unix_io_model.md) 8 | - [Java NIO](java_nio.md) 9 | - [Java内存模型](java_memory_model.md) 10 | - [RPC介绍](rpc.md) 11 | 12 | ## Advanced 13 | - [反射](java_reflection.md) 14 | - [静态工厂方法](java_static_factory_method.md) 15 | 16 | ## 多编程 17 | - [java多线程](java_thread.md) 18 | 19 | ## JavaWeb 20 | - [JSP](jsp.md) 21 | - [Servlet](servlet.md) 22 | 23 | ## IDE 24 | - [IntelliJ介绍](intellij.md) 25 | 26 | ## Demo 27 | - [动态代理](demos/d1) 28 | -------------------------------------------------------------------------------- /java/classloader.md: -------------------------------------------------------------------------------- 1 | # Java类的加载、链接及初始化 2 | 3 | Java代码是以字节数组(byte[])的形式存储的,而在JVM需要的是[java.lang.Class](http://docs.oracle.com/javase/8/docs/api/java/lang/Class.html)类对象。将字节码转化为类对象,需要通过加载,链接和初始化这三个步骤。 4 | 5 | ## 加载 6 | 类加载器用来加载Java类到JVM中,其可分为两类,一类是系统提供的,另一类是用户自定义的。系统提供的类加载器主要有如下三个: 7 | 8 | - Bootstrap ClassLoader 9 | 启动类加载器,Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库,如rt.jar, i18n.jar等。 10 | - Extension ClassLoader 11 | 扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/目录下的所有jar。 12 | - App ClassLoader 13 | 系统系统加载器。负责加载应用程序classpath目录下的所有jar和class文件。 14 | 15 | 用户可继承[java.lang.ClassLoader](https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html)来实现自定义类加载器。在加载类的过程中,从顶至底加载类-- Bootstrap ClassLoader --> Extension ClassLoader --> App ClassLoader --> user-definde ClassLoader。 16 | 17 | Java类加载器有两个比较重要的特性:层次组织结构和代理模式。层次组织结构指的是每个类加载器都有一个父类加载器,通过getParent()方法引用,类加载器通过这种父亲-后代的方式组织在一起,形成树状层次结构。代理模式指类加载器既可自己完成类的定义工作,也可代理给其他类加载器完成。上面说过类加载顺序是由顶至底尝试加载的,基于类加载器的树状层次结构,一般类加载器会先代理给父类加载器加载,当父类加载器加载失败时,才会尝试自己加载。这样的好处是避免重复加载,当父类加载器已经加载该类后,就没必要再加载一次了。 18 | 19 | 类加载器的一个重要用途是在JVM中为相同名称的Java类创建隔离空间。JVM在判断两个class是否相同时,不仅要判断两个类名是否相同,还要判断是否由同一个类加载器加载的。同一份字节码文件被两个不同的类加载器加载,JVM也会认为它们是不同的类。这个特性为相同名称的Java类在JVM共存创造了条件。 20 | 21 | ## 链接 22 | 链接指将类的字节码合并到JVM的运行状态中的过程。类的链接包括验证,准备和解析几个过程。验证用来确保Java类的结构正确,准备是创建Java类中的静态域,并将这些域的值设置为默认值,准备阶段不会执行代码。Java类可能包含对其他类或接口的引用,解析过程就是确保这些引用能被正确找到。 23 | 24 | 25 | ## 初始化 26 | 当类第一次被真正使用的时候,JVM会对该类进行初始化操作。初始化过程主要是执行静态代码块和初始化静态域。 27 | 28 | ## Reference 29 | - [Loading, Linking, and Initializing](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html) 30 | - [Class ClassLoader](https://docs.oracle.com/javase/8/docs/api/java/lang/ClassLoader.html) 31 | - [Understanding Extension Class Loading](https://docs.oracle.com/javase/tutorial/ext/basics/load.html) 32 | - [Java深度历险(二)——Java类的加载、链接和初始化](http://www.infoq.com/cn/articles/cf-Java-class-loader?utm_source=articles_about_java-depth-adventure&utm_medium=link&utm_campaign=java-depth-adventure) 33 | -------------------------------------------------------------------------------- /java/concurrency/README.md: -------------------------------------------------------------------------------- 1 | Java 并发编程实战阅读笔记 2 | 3 | ## ToRead 4 | - [ ] [guava](https://github.com/google/guava) 5 | - [ ] [netty](https://github.com/netty/netty) 6 | - [ ] [disruptor](https://github.com/LMAX-Exchange/disruptor) 7 | -------------------------------------------------------------------------------- /java/concurrency/java_concurrency_in_practice_note_01.md: -------------------------------------------------------------------------------- 1 | # 线程安全性 2 | ## 线程带来的风险 3 | - 安全性问题 4 | 多线程由于共享相同的内存地址空间,在并发运行时,可能会访问和修改其他线程正在使用的变量。 5 | - 活跃性问题 6 | 活跃性关注于“某件正确的事情最终会发生”。在多线程中,可能因为死锁,饥饿等问题,导致某线程永久等待资源而出现活跃性问题。 7 | - 性能问题 8 | 线程调度器临时挂起活跃线程转而运行其他线程,带来频繁的上下文切换操作,使 CPU 将更多时间花费在线程调度而不是线程运行上;另外线程共享数据时,必须使用同步机制,而这些机制往往会抑制某些编译器的优化,使用内存缓存区的数据无效,以及增加共享内存总线的同步流量。 9 | 10 | ## 线程安全性 11 | 要编写线程安全的代码,其核心在于对 *状态* 访问操作进行管理,特别是对 *共享* 状态和 *可变* 状态的访问。对象的状态是指存储在状态变量(如实例和静态域)中的数据。 12 | 对象的状态可能包括其他依赖对象的域。共享意味着变量可由多个线程同时访问,可变意味着变量的值在其生命周期内可发生变化。 13 | 14 | 多个线程访问某个状态变量且至少有一个线程执行写入操作时,必须使用同步机制来保证线程安全。Java 同步机制主要是指关键字 `synchronized`,其提供了独占的加锁方式。同步机制还包括 `volatile` 变量,显式锁及原子变量。 15 | 16 | ### 什么是线程安全性 17 | 在线程安全性的定义中,最核心的概念就是正确性。正确性的含义是某个类的行为与规范完全一样。良好的规范通常会定义各种不变性条件来约束对象的状态,以及定义各种后验条件来描述对象操作的结果。在对“正确性”给出一个较为清晰的定义后,就可以来定义线程安全性:当多个线程访问某个类时,这个类始终都能表现出正确的行为,那么就称这个类是线程安全的。 18 | 19 | 无状态对象(既不包含任何域,也不包含对任何其他域的引用)一定是线程安全的。 20 | 21 | ### 原子性 22 | 竞态条件:在并发编程中,由于不恰当的执行顺序而出现不正确结果的情况。最常见的竞态条件类型是“先检查后执行”:首先观察到某个条件为真,然后根据这个观察结果采用相应的动作,但事实上,**在观察到这个结果和采用相应动作之间,观察结果可能变得无效,从而导致各种问题**。 23 | 24 | 使用“先检查后执行”的一种常见情况就是延迟初始化。延迟初始化的目的是将对象初始化操作推迟到实际使用时才进行,同时确保只被初始化一次。常见的一种延迟初始化场景是懒汉式线程不安全的单例模式写法,很多教科书上也是这样教我们的,遗憾的是这种写法是错误的: 25 | ``` 26 | @NotThreadSafe 27 | public class Singleton { 28 | private static Singleton instance; 29 | 30 | public static Singleton getInstance() { 31 | if (instance == null) { 32 | instance = new Singleton(); 33 | } 34 | return instance; 35 | } 36 | } 37 | ``` 38 | 39 | 要避免竞态条件,就必须在某个线程修改变量时,通过某种方式防止其他线程使用这个变量,从而确保其他线程只能在修改操作完成之前或之后读取和修改变量。为了确保线程安全性,“先检查后执行”(如延迟初始化)和“读取-修改-写入”(如递增运算)等操作必须是原子的。将“先检查后执行”和“读取-修改-写入”等操作统称为复合操作:即包含一组必须以原子方式执行的操作。 40 | 41 | ### 加锁机制 42 | 上面说了复合操作需要以原子方式进行操作,那该怎么支持原子性呢? 43 | 44 | Java 提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized Block)。以关键字 `synchronized` 来修饰的方法就是一种横跨整个方法全的同步代码块,其中该同步代码块的锁就是方法调用所在的对象,静态的 `synchronized` 方法以 Class 对象作为锁。 45 | 46 | ``` 47 | synchronized (lock) { 48 | // 访问或修改由锁保护的共享状态。 49 | } 50 | ``` 51 | 线程在进入同步代码块之前会自动获得锁,在退出同步代码块时自动释放锁。无论是正常退出还是抛出异常退出代码块,获得锁的唯一途径就是进入这个由锁保护的同步代码块。 52 | 53 | 需要注意的是,虽然 `synchronized` 方法可以确保每个操作的原子性,但如果将多个原子操作合并为一个复合操作,还是需要额外的加锁机制。 54 | 55 | 一种常见的约定是,将所有会被多线程访问的可变状态都封闭在对象内部,通过对象的内置锁对所有访问可变状态的代码进行同步,从而使该对象上不会发生并发访问。对于每个包含多个变量的不变性条件,其中涉及的所有变量都需要由同一个锁来保护。 56 | ### 重入 57 | 疑问:书中的代码为什么父类会拿2次锁? 58 | 59 | 60 | ### 活跃性和性能 61 | 对在单个变量上实现原子操作来说,原子变量是很有用的,但若已经使用了 `synchronized` 关键字的代码块来构造原子操作,该操作中可不必使用原子变量,因为同时使用两种不同的同步机制不住会带来混乱,也不会在性能和安全性上带来任何好处。 62 | 63 | 当执行时候较长的计算或可能无法快速完成的操作时(如网络I/O或控制台I/O),一定不要持有锁。 64 | 65 | ### 小结 66 | 上述主要介绍了线程安全性方面的内容,介绍了什么是线程安全性,出现安全性问题一般是未能保证复合操作的原子性导致,解决方式是在保证活跃性和性能的前提下对复合操作加锁。 67 | 68 | 69 | -------------------------------------------------------------------------------- /java/demos/d1/src/samples/Animal.java: -------------------------------------------------------------------------------- 1 | package samples; 2 | 3 | /** 4 | * Created by maming on 16/6/23. 5 | */ 6 | public interface Animal { 7 | 8 | void run(); 9 | 10 | void say(); 11 | } 12 | -------------------------------------------------------------------------------- /java/demos/d1/src/samples/AnimalHandler.java: -------------------------------------------------------------------------------- 1 | package samples; 2 | 3 | import java.lang.reflect.InvocationHandler; 4 | import java.lang.reflect.Method; 5 | 6 | /** 7 | * Created by maming on 16/6/23. 8 | */ 9 | public class AnimalHandler implements InvocationHandler { 10 | 11 | private Object animal; 12 | 13 | public AnimalHandler(Object obj) { 14 | this.animal = obj; 15 | } 16 | 17 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 18 | // do something 19 | Object result = method.invoke(this.animal, args); 20 | //do other thing 21 | return result; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /java/demos/d1/src/samples/Cat.java: -------------------------------------------------------------------------------- 1 | package samples; 2 | 3 | /** 4 | * Created by maming on 16/6/23. 5 | */ 6 | public class Cat implements Animal { 7 | 8 | public void run() { 9 | System.out.println("samples.Cat run"); 10 | } 11 | 12 | public void say() { 13 | System.out.println("miaomiaomiao~~"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/demos/d1/src/samples/Dog.java: -------------------------------------------------------------------------------- 1 | package samples; 2 | 3 | /** 4 | * Created by maming on 16/6/23. 5 | */ 6 | public class Dog implements Animal { 7 | 8 | public void run() { 9 | System.out.println("samples.Dog run"); 10 | } 11 | 12 | public void say() { 13 | System.out.println("wangwangwang~~"); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /java/demos/d1/src/samples/ProxyTest.java: -------------------------------------------------------------------------------- 1 | package samples; 2 | 3 | import java.lang.reflect.Proxy; 4 | 5 | /** 6 | * Created by maming on 16/6/23. 7 | */ 8 | public class ProxyTest { 9 | 10 | public static void main(String[] args) { 11 | Dog dog = new Dog(); 12 | ClassLoader loader = dog.getClass().getClassLoader(); 13 | Class[] it = dog.getClass().getInterfaces(); 14 | AnimalHandler ah = new AnimalHandler(dog); 15 | Animal animal = (Animal) Proxy.newProxyInstance(loader, it, ah); 16 | animal.say(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /java/demos/d1/testDynamicProxy.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /java/img/ObjectLifetime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/ObjectLifetime.png -------------------------------------------------------------------------------- /java/img/cms.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/cms.gif -------------------------------------------------------------------------------- /java/img/deletion_with_compact.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/deletion_with_compact.png -------------------------------------------------------------------------------- /java/img/gc_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_1.png -------------------------------------------------------------------------------- /java/img/gc_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_2.png -------------------------------------------------------------------------------- /java/img/gc_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_3.png -------------------------------------------------------------------------------- /java/img/gc_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_4.png -------------------------------------------------------------------------------- /java/img/gc_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_5.png -------------------------------------------------------------------------------- /java/img/gc_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_6.png -------------------------------------------------------------------------------- /java/img/gc_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_7.png -------------------------------------------------------------------------------- /java/img/gc_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/gc_8.png -------------------------------------------------------------------------------- /java/img/hotspot_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/hotspot_heap.png -------------------------------------------------------------------------------- /java/img/hotspot_jvm_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/hotspot_jvm_architecture.png -------------------------------------------------------------------------------- /java/img/intellij/mvn_tomcat_add.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/intellij/mvn_tomcat_add.jpg -------------------------------------------------------------------------------- /java/img/intellij/mvn_tomcat_conf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/intellij/mvn_tomcat_conf.jpg -------------------------------------------------------------------------------- /java/img/intellij/mvn_tomcat_edit_con.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/intellij/mvn_tomcat_edit_con.jpg -------------------------------------------------------------------------------- /java/img/intellij/mvn_tomcat_new.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/intellij/mvn_tomcat_new.jpg -------------------------------------------------------------------------------- /java/img/java_io_model/asyn_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/asyn_io.png -------------------------------------------------------------------------------- /java/img/java_io_model/blocking_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/blocking_io.png -------------------------------------------------------------------------------- /java/img/java_io_model/comparison.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/comparison.png -------------------------------------------------------------------------------- /java/img/java_io_model/io_multiplexing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/io_multiplexing.png -------------------------------------------------------------------------------- /java/img/java_io_model/nonblocking_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/nonblocking_io.png -------------------------------------------------------------------------------- /java/img/java_io_model/signal_driven_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/java_io_model/signal_driven_io.png -------------------------------------------------------------------------------- /java/img/jstl_core_tag.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/jstl_core_tag.jpg -------------------------------------------------------------------------------- /java/img/jstl_fmt_tag_library.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/jstl_fmt_tag_library.jpg -------------------------------------------------------------------------------- /java/img/jstl_function_tag_library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/jstl_function_tag_library.png -------------------------------------------------------------------------------- /java/img/jstl_sql_tag_library.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/jstl_sql_tag_library.png -------------------------------------------------------------------------------- /java/img/jstl_xml_tag_library.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/jstl_xml_tag_library.jpg -------------------------------------------------------------------------------- /java/img/marking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/marking.png -------------------------------------------------------------------------------- /java/img/normal_deletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/normal_deletion.png -------------------------------------------------------------------------------- /java/img/rpc/rpc-component.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/rpc/rpc-component.jpg -------------------------------------------------------------------------------- /java/img/staticProxy.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/java/img/staticProxy.gif -------------------------------------------------------------------------------- /java/intellij.md: -------------------------------------------------------------------------------- 1 | # IntelliJ IDEA 2 | 3 | ## IntelliJ Community 集成 Tomcat 4 | Ultimate版下载Tomcat and TomEE插件安装即可,但Community版并没有该插件。若需要使用Web Server,可以使用Jetty或Maven运行的Tomcat。以下简单介绍下如何配置Maven运行的tomcat。 5 | 6 | - 新建项目,如下: 7 | ![create_new_project](img/intellij/mvn_tomcat_new.jpg) 8 | 9 | - 修改pom.xml,添加如下行: 10 | ``` 11 | 12 | 13 | 14 | 15 | org.apache.tomcat.maven 16 | tomcat7-maven-plugin 17 | 2.2 18 | 19 | 9090 20 | / 21 | UTF-8 22 | tomcat7 23 | 24 | 25 | 26 | 27 | ``` 28 | 29 | - 点击Edit Configurations,添加Maven配置。 30 | ![edit_configurations](img/intellij/mvn_tomcat_edit_con.jpg) 31 | ![add_mvn](img/intellij/mvn_tomcat_add.jpg) 32 | 33 | - 编辑该Maven配置 34 | ![maven_conf](img/intellij/mvn_tomcat_conf.jpg) 35 | 36 | Tomcat Goal可参考[Plugin Documentation](http://tomcat.apache.org/maven-plugin-2.2/tomcat7-maven-plugin/plugin-info.html),这里选择`tomcat7:run`。 37 | 38 | - 运行该Tomcat,打开http://localhost:9090,可以看到"Hello World!"字样。 39 | 40 | ps: Community相比Ultimate功能缺失有点多了,不过Ultimate价格又有点贵了-,- 41 | 42 | ## 快捷方式 43 | 44 | 先说下 Mac 中各[修饰键](https://support.apple.com/zh-cn/HT201236)的符号,如下: 45 | 46 | 修饰键 | 符号 47 | ---------|---------- 48 | Command | ⌘ 49 | Option | ⌥ 50 | Caps Lock | ⇪ 51 | Shift | ⇧ 52 | Control | ⌃ 53 | Fn | | 54 | 55 | 56 | ### 快捷键 57 | 58 | 功能 | 快捷键 59 | ------------|---------------- 60 | 折叠代码块 | ⇧⌘. 61 | 62 | 63 | ### 快捷方法 64 | 输入快捷方法后,再按TAB键即显示相关Java代码。 65 | 66 | Java代码 | 快捷方法 67 | ----------------------|---------------- 68 | System.out.println | sout 69 | 70 | 71 | 另外,可通过`Live Templates`功能,构建相关快捷方式,如构建main方法: 72 | ``` 73 | public static void main(String[] args) { 74 | 75 | } 76 | ``` 77 | -------------------------------------------------------------------------------- /java/java_memory_model.md: -------------------------------------------------------------------------------- 1 | # Java内存模型 2 | 3 | ## 什么是内存模型 4 | 内存模型定义了某一CPU写内存,其他CPU也对该数据可见的充要条件。由于如下几种情况的存在: 5 | 6 | - CPU缓存。多核CPU系统中,CPU通常都有多层缓存结构。CPU直接操作的是缓存中的数据。在某些时刻,CPU缓存中的数据与内存中的数据可能存在不一致的情况。 7 | - CPU指令[乱序执行](https://zh.wikipedia.org/wiki/%E4%B9%B1%E5%BA%8F%E6%89%A7%E8%A1%8C)。为避免CPU在运算对象不可获取时的大量等待,CPU会在某些改变指令的执行顺序。 8 | - 编译器的代码重排。出于性能优化的考虑,在不改变程序语义的情况,编译器会对代码进行重排。 9 | 10 | 有必要对Java程序访问和操作主存的方式进行规范。[Java内存模型](http://www.cs.umd.edu/~pugh/java/memoryModel/)即为解决这个问题而引入的。一些CPU实现强内存模型,即任何时刻所有CPU见到内存中的值都一样的。一些CPU实现较弱的内存模型,通过内存屏障来刷新或过期CPU缓存的数据,来达到所有CPU看到的数据一致这一目的。Java内存模型描述了多线程代码中哪些行为是合法的,以及线程在内存的交互方式。 11 | 12 | Java提供了一些语言级别的支持用以帮助多线程编程,如`volatile`,`final`,`synchronized`等关键字。Java内存模型定义了`volatile`和`synchronized`的行为,并且保证正确的synchronize代码能在所有CPU架构都能正确运行。 13 | 14 | 15 | 16 | 17 | 18 | ## 参考 19 | - [Memory Model](https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.4) 20 | - [JSR 133 (Java Memory Model) FAQ](http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html) 21 | - [Memory Barriers: a Hardware View for Software Hackers](http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf) 22 | -------------------------------------------------------------------------------- /java/java_nio.md: -------------------------------------------------------------------------------- 1 | ## Java NIO 2 | 3 | *注:本文主要参考[Java NIO Tutorial](http://tutorials.jenkov.com/java-nio/index.html)*。 4 | 5 | 在Java SE1.4之前,Java io主要为阻塞io,其主要分为character streams 和 byte streams,还有其他如Console, File, StreamTokenizer等接口。而character straem又可分为Reader和Writer两类,byte stream分为InputStream和OutputStream。 6 | 7 | Java IO面向流,每次从流中读取一个或多个字节,并且是阻塞的,因此在Java SE1.4之前Java在处理IO方面比较弱,在Java SE1.4中引入了nio,其面向块且是非阻塞的,主要分为Buffer, Channel, Selector三块,另外还有charset。这里主要说下NIO方面的内容。 8 | 9 | ### NIO概述 10 | 11 | 如上所述,NIO主要分为Buffer,Channel和Selector。其关系如下: 12 | 13 | ``` 14 | /------> Channel <--------> Buffer 15 | | 16 | Thread ---> Selector ---|------> Channel <--------> Buffer 17 | | 18 | `------> Channel <--------> Buffer 19 | ``` 20 | 21 | Selector允许单线程处理多个Channel。 22 | 23 | ### Channel 24 | 既能从Channel中读取数据,也能写数据到Channel,主要有如下几种重要的Channel实现: 25 | - FileChannel 26 | 从文件中读写数据。 27 | - DatagramChannel 28 | 通过NDP读写网络数据报中的数据。 29 | - SocketChannel 30 | 通过TCP读写网络数据报中的数据。 31 | - ServerSocketChannel 32 | 监听新进来的TCP连接,对每个新进来的连接都会创建一个SocketChannel。 33 | 34 | Java NIO支持scatte/gather,scatter从Channel中读取指将读取的数据写入多个Buffer中。gatter写入Channel指将多个Buffer的数据写入同一个Channel。Channel间数据可以通过`transferFrom()`和`transferTo()`互相传输。 35 | 36 | ### Buffer 37 | 使用Buffer读写数据,一般遵循如下四个步骤: 38 | - 写数据到Buffer 39 | - 调用`flip()`将Buffer从写模式切到读模式。 40 | - 从Buffer中读取数据。 41 | - 调用`clear()`或`compact()`清空缓冲区。`clear()`清空整个缓冲区,`compact()`只清除已经读过的数据。 42 | 43 | Buffer有三个属性: 44 | - capacity 45 | - position 46 | - limit 47 | 48 | position和limit的含义取决于Buffer处于读模式或写模式。capacity即Buffer容量,一旦满了需要清空才能继续写数据。position表示当前位置,当数据写入buffer后,position向前移动到下一个可写入数据的Buffer单元中工,读取时position也会向前移动到下一个可读的位置。若从写模式切换到读模式,position会被重置为0。在写/读模式中,limit表示最多还能往/从Buffer写/读多少数据,从写模式切换到读模式时,limit会被设置成写模式下的position值。 49 | 50 | ### Selector 51 | 通过Selector可向多个Channel中读写数据,Channel须先注册到Selector才能与之使用,使用Selector的Channel须处于非阻塞模式下,即FileChannel不能与Selector配置使用,因其不能切换到非阻塞模式。如下是Channel注册到Selector的例子: 52 | ``` 53 | // 创建Selector 54 | Selector selector = Selector.open(); 55 | // channel设置为非阻塞模式 56 | channel.configureBlocking(false); 57 | // channel注册到Selector上 58 | SelectionKey key = channel.register(selector, SelectionKey.SelectionKey.OP_READ | SelectionKey.OP_WRITE); 59 | ``` 60 | 61 | 通过register()向Selector注册后会返回一个SelectionKey对象。其有如下属性: 62 | 63 | - interest集合 64 | 所选择的操作的集合:主要有OP_CONNECT,OP_ACCEPT,OP_READ,OP_WRITE等。 65 | - ready集合 66 | Channel是否准备好的集群。 67 | - Channel 68 | 通过SelectionKey访问Channel:`Channel channel = selectionKey.channel();`。 69 | - Selector 70 | 通过SelectionKey访问Selector:`Selector selector = selectionKey.selector();`。 71 | - 附加的对象 72 | 将更多对象或信息通过attach()方法附加到SelectionKey上。 73 | 74 | 注册过后,可通过Selector的`select()`方法选中已经准备好的通道。用完Selector后需要调用其`close()`将其关闭。 75 | 76 | 其他更多内容此不详述。若希望更加深入了解这部分内容,可看下netty等的实现。 77 | 78 | ## 参考 79 | - [Java nio vs Javaio](https://blogs.oracle.com/slc/entry/javanio_vs_javaio) 80 | - [java io api](https://docs.oracle.com/javase/7/docs/api/java/io/package-summary.html) 81 | - [java nio api](https://docs.oracle.com/javase/7/docs/api/java/nio/package-summary.html) 82 | -------------------------------------------------------------------------------- /java/java_reflection.md: -------------------------------------------------------------------------------- 1 | # Java Reflection 2 | 当程序运行在 JVM 中时,经常需要检查或修改程序运行时的行为,对于这种需求,Java 提供了 **反射** 这一特性。通过反射,能获取到类的如下一些信息: 3 | - Class对象 4 | - 类名 5 | - 修饰符 6 | - 包信息 7 | - 父类 8 | - 构造器 9 | - 方法 10 | - 变量 11 | - ... 12 | 13 | 更多信息可参考 [java.lang.Class](http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html)。这里简单介绍下反射的相关内容。 14 | 15 | ## Class 16 | Java 对象有两种类型:基础类型(如 int, char 等)和引用类型(如 String, Double, Serializable),对于每种类型的对象,JVM 实例化一个与之关联的 [java.lang.Class](http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html) 对象,Class 提供了创建类和对象的方法,同时该实例是所有反射 API 的入口。 17 | 18 | ### Object.getClass() 19 | 20 | 如果一个对象继承自 [Object](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html) 且其实例可用,获取它的 Class 对象最简单的方法是调用 [Object.getClass()](https://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#getClass--),如下: 21 | 22 | ``` 23 | Class c = "foo".getClass(); 24 | ``` 25 | 26 | ### .class 语法 27 | 28 | 如果对象还未被实例化,获取 Class 即获取类型的 Class,此时需使用类型后加 `.class` 方法,如下: 29 | ``` 30 | boolean b; 31 | Class c = b.getClass(); // compile-time error 32 | 33 | Class c = boolean.class; // correct 34 | ``` 35 | 对于基础类型,这是最简单获取 Class 的方法。 36 | 37 | ### Class.forName() 38 | 如果类的全名(即包括包名)可用,可使用 [Class.forName()](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#forName-java.lang.String-) 获取 Class ,这种方式不能用于基础类型。 39 | 40 | ``` 41 | Class c = Class.forName("com.duke.MyLocaleServiceProvider"); 42 | ``` 43 | ### 基础类型的 TYPE 属性 44 | 除了 `.class` 获取基础类型的 Class,还可以通过基础类型的 TYPE 属性,如`Class c = Double.TYPE;` 45 | 46 | ### 返回 Classes 的方法 47 | 如 [Class.getSuperclass()](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getSuperclass--) 和 [Class.getClasses()](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getClasses--) 等均能返回 class 对象。 48 | 49 | ## Constructor 50 | 51 | 获取到 Class 对象后,可通过 [getDeclaredConstructors()](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredConstructors--) 和 [getConstructors](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getConstructors--) 获取类的 Constructor 数组。当然,如果知道要访问的构造函数的方法参数类型,可将相应参数的 Class 对象做为参数传给 getDeclaredConstructors() 或 getConstructors() 以得到指定构造方法,如下: 52 | ``` 53 | Constructor constructor = 54 | aClass.getConstructor(new Class[]{String.class}, bClass.class); 55 | ``` 56 | 获取到 Constructor 对象后,可使用 [newInstance()](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Constructor.html#newInstance-java.lang.Object...-) 实例化一个类,该方法的参数需对应构造方法的参数类型。如对于上述构造方法,可使用如下方法实例化类: 57 | ``` 58 | AClass aClass2 = aClass.newInstance("String1", new BClass(param1, param2)); 59 | ``` 60 | 61 | ## Field 62 | 63 | 获取到 Class 对象,可通过 [getFields](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getFields--) 和 [getField(String name)](https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getField-java.lang.String-) 来取得 [Field](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Field.html) 变量,取得 Field 对象后,即可取得变量相关的内容。 64 | 65 | 66 | ## References 67 | - [Trail: The Reflection API](https://docs.oracle.com/javase/tutorial/reflect/index.html) 68 | 69 | -------------------------------------------------------------------------------- /java/java_socket.md: -------------------------------------------------------------------------------- 1 | # Socket 编程 2 | 3 | 4 | -------------------------------------------------------------------------------- /java/java_static_factory_method.md: -------------------------------------------------------------------------------- 1 | # 静态工厂方法 2 | 3 | ## 简介 4 | 在 《Effective Java》的 Item 1 中,提到了静态工厂方法,即一个返回类实例的静态方法,并补充说明和设计模式中的工厂方法模式不同。如下是 JDK1.7 源码中的一个例子: 5 | 6 | ``` 7 | public final class Boolean implements java.io.Serializable, 8 | Comparable 9 | { 10 | // 缓存 TRUE 和 FALSE 两个对象。 11 | public static final Boolean TRUE = new Boolean(true); 12 | public static final Boolean FALSE = new Boolean(false); 13 | 14 | private final boolean value; 15 | 16 | public Boolean(boolean value) { 17 | this.value = value; 18 | } 19 | 20 | public static Boolean valueOf(boolean b) { 21 | return (b ? TRUE : FALSE); 22 | } 23 | } 24 | ``` 25 | 26 | 这里的 `valueOf()` 就是一个静态方法,其用来产生一个 Boolean 对象。可以看到,静态工厂方法和类的构造方法类似,都用于返回一个对象。首先思考下,为什么该方法要是静态的?稍微思考便知只有该方法是静态方法才能返回实例。那么,静态工厂方法相比构造方法有什么优缺点呢?这里参照 《Effective Java》中说明,列出其优缺点。 27 | 28 | ## 优点 29 | - 相比构造方法而言,静态工厂方法具有更加可读的方法名。对于构造方法而言,很难知晓不同构造方法对应的各参数的类型,而使用静态工厂方法,可以通过更可读的方法名来区别多个静态工厂方法的区别。 30 | - 静态工厂方法不需要每次调用时都创建新的对象。静态工厂方法允许不可变类使用预先初始化过的实例,或同上面 Boolean 类一样,缓存其创建的实例对象(查看各原始数据类型的封装类,基本都是通过这种方法实现的)。 31 | - 静态工厂方法还可以返回该类型的子类对象。这让静态工厂方法的扩展性远远大于构造方法,这种情况的实例之一是 JDK 源码中的 EnumSet 类型,其根据参数中的元素个数返回不同类型的实例。 32 | - 静态工厂方法可以简化参数化类型对象的创建过程。如下是例子: 33 | ``` 34 | Map> m = new HashMap>(); 35 | 36 | public static HashMap newInstance() { 37 | return new HashMap(); 38 | } 39 | 40 | Map> m = HashMap.newInstance(); 41 | ``` 42 | 第一行可以简化成第三行代码。 43 | 44 | ## 缺点 45 | 当然,静态工厂方法也是有如下一些缺点的。 46 | - 如果一个类的构造方法类型为 private,只提供静态工厂方法来创建对象,那么将不能使用继承的方式来扩展该类。不过一般而言,在扩展类时,优先使用组合而不是继承的方式。 47 | - 静态工厂方法不能很好的和其他静态类区别开。若使用静态工厂方法代替构造方法,我们很难一眼认出需要使用哪个静态方法来创建对象,当然可以在 Javadoc 中说明;另外,使用注释进行说明和合理的给静态工厂方法取名,也能有效的避免这个问题。为和普通静态方法区别开来,《Effective Java》建议命名静态工厂方法时,遵循如下规则: 48 | - valueOf -- 返回一个返回值和参数相同的对象。这种静态方法命名通常用于类型转换。 49 | - of -- 和 valueOf 类似。 50 | - getInstance -- 根据参数返回对应的对象,该对象可能是缓存对象池中的对象。对于 Singleton 模式,使用无参的 getInstance 方法,并且总是返回同一对象。 51 | - newInstance -- 和 getInstance 类似,不过每次返回的都是新创建的对象。 52 | - get*Type* -- 和 getInstance 类似,不过返回的对象是另外一个不同类型(_Type_ 类型)的类。 53 | - new*Type* -- 和 newInstance 类似,不过每次返回的都是新创建的不同类型(_Type_ 类型)的类。 54 | 55 | -------------------------------------------------------------------------------- /java/java_thread.md: -------------------------------------------------------------------------------- 1 | # Java多线程 2 | 3 | 线程安全? 4 | 5 | 线程的几种状态 6 | 7 | 两者实现方式。 8 | 9 | ## wait sleep等方法区别 10 | 11 | 12 | ## synchronized 13 | 无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁。在同步块中,锁的即synchronized的参数。对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。 14 | 15 | 16 | ## ThreadLocal 17 | 18 | ## 线程池 19 | 使用线程池优点: 20 | - 不用每次新建对象,效率更高。 21 | - 方便管理, 22 | - 功能丰富,支持定时执行等功能。 23 | - 避免this逃逸问题。 24 | 25 | ### ExecutorService 26 | 27 | Java支持如下线程池: 28 | - newCachedThreadPool 29 | - newFixedThreadPool 30 | - newScheduledThreadPool 31 | - newSingleThreadExecutor 32 | 33 | 34 | ## Callable和Future 35 | 36 | 37 | -------------------------------------------------------------------------------- /java/java_unix_io_model.md: -------------------------------------------------------------------------------- 1 | # Java与unix的I/O模型 2 | 3 | ## Unix I/O模型 4 | 5 | Unix下有五种I/O模型: 6 | - 阻塞I/O (blocking I/O model) 7 | - 非阻塞I/O (nonblocking I/O model) 8 | - I/O复用 (I/O multiplexing model: select 和poll) 9 | - 信号驱动式I/O (signal-driven I/O model) 10 | - 异步I/O (asynchronous I/O model) 11 | 12 | 在数据写入时,这些模型主要在如下两方面有区别: 13 | - 等待数据准备。 14 | - 将数据从内核拷贝到进程。 15 | 16 | 以下具体说下这5种模式。 17 | 18 | ### 阻塞I/O模型 19 | 最常见的I/O模型即阻塞I/O模型,默认情况下,所有的socket都是阻塞的。如下是阻塞I/O的流程: 20 | 21 | ![阻塞I/O模型图](img/java_io_model/blocking_io.png) 22 | 23 | 如上图所示,当进程调用`recfrom`时,直到数据准备好再将数据从内核拷贝给进程空间并返回,进程才继续执行,否则会一直阻塞。 24 | 25 | ### 非阻塞I/O模型 26 | 当socket设置为非阻塞时,如果数据未准备好,内核会返回错误代码`EWOULDBLOCK`不让进程处于sleep状,I/O流程如下: 27 | 28 | ![非阻塞I/O模型图](img/java_io_model/nonblocking_io.png) 29 | 30 | - 对于前3个`recvfrom`,由于数据还未准备好,内核返回错误`EWOULDBLOCK`。 31 | - 当第4次调用`recvfrom`,数据已准备好,于是数据从内核拷贝到进程空间中,进程阻塞直到内核返回结果。 32 | 33 | 如上图,非阻塞I/O模型中进程会主动循环的调用`recvfrom`询问数据是否准备好,这称为 **polling**。非阻塞I/O比较浪费CPU时间,因此不太常用,一般是在其他I/O模型中使用非阻塞I/O这一特性。 34 | 35 | ### I/O复用模型 36 | I/O复用会使用到`select`和`poll`两个函数,这两个函数也会使用线程阻塞,但同阻塞I/O不同的是,这两个函数会同时阻塞多个I/O操作且同时对多读写的函数进行检测,直到有数据可用时,才真正调用I/O操作函数。流程如下: 37 | 38 | ![I/O复用模型](img/java_io_model/io_multiplexing.png) 39 | 40 | 用户调用select,那么整个进程被select调用(而不是socket IO)block,同时内核会监听所有select负表的socket,当任何一个socket数据准备好了,select会返回,此时用户进程再调用`recvfrom`,将数据从内核拷贝到进程空间。 41 | 42 | I/O复用看起来和阻塞I/O差不多,由于I/O复用会使用两次系统调用(select和recvfrom),而阻塞I/O只使用一次系统调用(recvfrom),看起来I/O复用更差。其实不然,select的优势在于能同时处理多个连接。 43 | 44 | 同I/O复用模型比较类似的是多进程加阻塞I/O模型这个组合。区别在于I/O复用是使用一个select调用block多个阻塞,而多进程加阻塞I/O是每个进程被一个系统调用阻塞(如redvfrom)。 45 | 46 | ### 信号驱动I/O模型 47 | 48 | 信号驱动I/O模型使用信号`SIGIO`来通知数据准备好了。如下图: 49 | 50 | ![信号驱动I/O模型](img/java_io_model/signal_driven_io.png) 51 | 52 | - 首先允许socket使用信号驱动,然后使用`sigaction`系统调用安装信号处理函数,接着立即返回,这样进程不会被阻塞。 53 | - 当数据准备好后,内核返回`SIGIO`信号给进程。在拷贝数据给进程过程中,进程阻塞。 54 | 55 | 信号驱动一般不太常用。 56 | 57 | ### 异步I/O模型 58 | 进程发起系统调用后可立即返回。当内核将数据拷贝到进程空间后再通知进程去取,整体过程如下: 59 | 60 | ![异步I/O模型](img/java_io_model/asyn_io.png) 61 | 62 | 63 | ### I/O模式比较 64 | 65 | 如下图: 66 | 67 | ![IO模型对比](img/java_io_model/comparison.png) 68 | 69 | 前四种I/O只要是第一阶段(即数据阶段)不同,第二阶段都会阻塞进程。而异步I/O不会阻塞进程。 70 | 71 | ### 同步与异步 72 | 73 | POSIX对于同步I/O和异步I/O的定义如下: 74 | 75 | - 同步I/O即阻塞进程直到I/O操作完成。 76 | - 异步I/O不会阻塞进程。 77 | 78 | 按这个定义,前面四种I/O都是同步I/O模型。只有异步I/O模型是异步I/O。 79 | 80 | ## Java I/O 模型 81 | 82 | 当前Java有三个不同的I/O包: 83 | 84 | - IO 85 | 同步阻塞。基于字节,对于每一个客户端的socket连接都需要一个线程来处理,并且在此期间,该线程会被一直占用。 86 | - NIO 87 | 同步非阻塞,该包中的[java.nio.channels.SelectorProvider](https://docs.oracle.com/javase/8/docs/api/java/nio/channels/spi/SelectorProvider.html)实现基于Linux的epoll机制(多路复用I/O模型)。客户端发送的请求会注册到多路复用器上,多路复用轮询到有I/O请求时会启动一个线程进行处理。NIO基于块。 88 | - AIO 89 | 异步非阻塞。于JDK7发布。客户端发送请求,等操作系统完成相关操作后再通知客户端处理。 90 | 91 | 关于NIO的内容,见[Java NIO](java_nio.md)。 92 | 93 | ## 参考 94 | - [Chapter 6. I/O Multiplexing: The select and poll Functions](https://notes.shichao.io/unp/ch6/) 95 | - [Enhancements in Java I/O](https://docs.oracle.com/javase/8/docs/technotes/guides/io/enhancements.html) 96 | -------------------------------------------------------------------------------- /java/maven/maven.md: -------------------------------------------------------------------------------- 1 | Maven 2 | === 3 | 4 | 这里记录下在 使用Maven时的一些知识点。 5 | 6 | Installation 7 | --- 8 | 在[Apache Maven Project](http://maven.apache.org/download.cgi)中下载maven,解压并按照`README.txt`配置。运行`mvn -v`查看是否配置成功。 9 | 10 | Configuring Maven 11 | --- 12 | 根据`setting.xml`知,有两种级别的配置: User Level 和 Global Level。`localRepository`默认为` ${user.home}/.m2/repository/`。 13 | 14 | Creating a project 15 | --- 16 | 这里以"hello world"程序为例,说下创建maven应用的大致步骤。参考官方文档,运行命令如下: 17 | - `mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DinteractiveMode=false`。 18 | `archetype`是Maven的一个模板工具包,帮助我们快速创建一个Maven工程的主干。`mvn -D`定义系统属性,如`-DartifactId`定义了应用的名称,`-DinteractiveMode=false`的意思是指令执行过程中选择默认选项,这些参数将传递给archetype中的goals。生成的`pom.xml`是maven的核心配置文件。 19 | 20 | - `mvn package` 21 | package是[build lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html)中的一步。这条命令将lifecycle从头一直执行到package这一步。这步可以看到生成的jar包。 22 | 23 | - `java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App` 24 | 检查生成的jar包,这条命令的结果是`Hello World!` 25 | 26 | Lifecycle、Phase && Goal 27 | --- 28 | 这里说下上面这些命令的运行机制。mvn命令是`mvn [options] [] []`这样的。其中`option`这部分可以使用`mvn -h`查看,这里说下goal和phase. 29 | 30 | ### lifecycle 31 | Maven是基于构建的生命周期(a build lifecycle)这个概念的,完成Maven工程对应着完成相应的生命周期。有三个内置的生命周期: default, clean 和 site.default生命周期处理工程的发布,clean生命周期处理工程的清理,而site生命周期处理创建工程的site文档。 32 | 33 | ### phases 34 | lifecycle是由一系列不同的phases组成的。如default生命周期有以下这些phases: 35 | 36 | - validate 37 | - compile 38 | - test 39 | - package - 将compiled code打成指定格式包,如JAR 40 | - integration-test 41 | - verify 42 | - install - 安装package到本地repository 43 | - deploy 44 | 45 | 执行完default的生命周期意味着执行了以上所有的phases。如果选择执行到某个phase,该phase之前的所有phases都将被执行。 46 | 47 | ### goals 48 | 然而,即使phase对lifecycle中每个指定的步骤负责,但完成这个步骤的方法仍然很多,所以指定"plugin goals"来约束这些phases."plugin goal"代表了一个指定的任务,这个任务负责创建和管理一个工程。 49 | 50 | 调用goals和phases的顺序决定了build liftcycle的执行顺序。以`mvn clean dependency:copy-dependencies package`为例,如果这个命令被执行,意味着"clean phase"被执行(这会执行clean lifecycle中在clean之前的所有phases,包括clean phase本身),接着执行"dependency:copy-dependencies goal",最后执行"package phase"(同样的,default lifecycle中package之前包括package phases都将被执行。) 51 | 52 | 一个build phase可以有0个或者多个goals来约束它。如果一个build phase没有一个goals来约束它,这个build phase将不会被执行。如果有多个goals约束它,这些goals都会被执行。 53 | 54 | ### 使用build lifecycle建立工程 55 | 当初初始化一个Maven工程时,怎样给这些phases指定goals呢? 56 | 57 | #### packaging 58 | 第一种方法是为pom.xml中元素设置packaging值。默认packaging 值是jar。每个packaging都包含一系列goals绑定到特定的phase。这也是为什么上述build phase没有指定goals却还能执行的原因。 59 | 60 | #### plugins 61 | 第二种方法是给phases添加goals。Plugins是能给Maven提供goals的工件(artifacts),plugins包含了lifecycle pahse绑定哪些goals的信息。如果多个goals约束着一个特定的phase,那么将会优先执行"packaing"中的goals,接着是POM中的这些定义。可以使用更大程度的控制这些goals的执行顺序。 62 | 63 | 以下是一个例子: 64 | ``` 65 | ... 66 | 67 | org.codehaus.modello 68 | modello-maven-plugin 69 | 1.4 70 | 71 | 72 | 73 | 74 | src/main/mdo/maven.mdo 75 | 76 | 4.0.0 77 | 78 | 79 | java 80 | 81 | 82 | 83 | 84 | ... 85 | ``` 86 | 87 | Others 88 | --- 89 | - 删除一个project 90 | 在project目录上,运行`mvn clean packege`即可删除一个project。 91 | 92 | 93 | Reference List 94 | --- 95 | - [Maven in 5 Minutes](http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html) 96 | - [Available Plugins](http://maven.apache.org/plugins/index.html) 97 | - [Introduction to the Build Lifecycle](http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html) 98 | -------------------------------------------------------------------------------- /java/netty/intro.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | __说明:本文基于官网,旨在快速了解 Netty 是什么,并了解其作用及优点,然后运行一次基于 Netyy 的demo。__ 4 | 5 | ## 三大问题之一:Netty 是什么? 6 | 参见官网说明: 7 | > The Netty project is an effort to provide an asynchronous event-driven network application framework and tooling for the rapid development of maintainable high-performance · high-scalability protocol servers and clients. 8 | 9 | 即 Netty 企图提供 **异步事件驱动网络服务框架**和**快速开发可维护的高性能 · 高扩展性服务端和客户端协议的工具集** 。换句话说,Netty 是一个 **NIO 客户端服务端框架**,它使得快速而简单的开发像服务端客户端协议的网络应用成为可能。 10 | 11 | ## 三大问题之二:Netty 的优点 12 | Netty 在吸取大量协议实现(如FTP,SMTP,HTTP以及各种二进制、基于文本的传统协议)的经验上进行了精心的设计,这使得 Netty 成功找到了一种无需妥协就能满足程序的简易开发、性能、稳定性和灵活性等要求的方法。 13 | 14 | Netty 依赖的**哲学**使其与其他网络应用框架有很大的不同,Netty 被设计成保证用户在 API 和实现上有着最佳体验。 15 | 16 | 目前看下来,上面叙述还是很虚的,云里雾里。 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /java/rpc.md: -------------------------------------------------------------------------------- 1 | # RPC简介 2 | 3 | 参考维基百科中的定义,RPC全称为Remote Procedure Call,是一种通信协议,该协议允许程序调用另一计算机的子程序,而无须为这个交互编写额外的代码。即程序员调用本地函数和RPC函数,方法基本相同。 4 | 5 | ## 目标 6 | 做为RPC概念的提出者,Nelson在[Implementing Remote Procedure Calls](http://birrell.org/andrew/papers/ImplementingRPC.pdf)中提出了RPC系统的几个目标: 7 | 8 | - 简单 9 | RPC应该和本地函数调用一样简单,这样分布式计算会更加容易。 10 | - 高效 11 | - 安全 12 | 13 | 考虑到编程语言不一定提供了能表示远程地址的方法,即使提供了远程地址的表示方法,不同计算机间使用共享地址空间的代价也可能大于实际收益,因此RPC舍弃了在不同计算机之前仿真共享地址空间。另外,为保证RPC尽可能的同本地方法调用,一些重要的分布式计算特性,如timeout ,在设计RPC时会被排除。 14 | 15 | ## 结构 16 | 17 | Nelson指出实现RPC的程序包括如下5个理论部分: 18 | 19 | - user 20 | - user-stub 21 | - RPCRuntime 22 | - server-stub 23 | - server 24 | 25 | 26 | 整个结构如图: 27 | 28 | ![component](img/rpc/rpc-component.jpg) 29 | 30 | ## 参考 31 | - [Implementing Remote Procedure Calls](http://birrell.org/andrew/papers/ImplementingRPC.pdf) 32 | - [Remote Procedure Call Programming Guide](https://docs.freebsd.org/44doc/psd/23.rpc/paper.pdf) 33 | - [Remote Procedure Call](https://christophermeiklejohn.com/pl/2016/04/12/rpc.html) 34 | - [RPC 的概念模型与实现解析](http://mindwind.me/blog/2016/05/22/RPC-%E7%9A%84%E6%A6%82%E5%BF%B5%E6%A8%A1%E5%9E%8B%E4%B8%8E%E5%AE%9E%E7%8E%B0%E8%A7%A3%E6%9E%90.html) 35 | -------------------------------------------------------------------------------- /java/servlet.md: -------------------------------------------------------------------------------- 1 | ## Servlet简介 2 | 3 | ### servlet生命周期 4 | 5 | ### filter 6 | 7 | ### 参考 8 | - [Java Servlet Technology](https://docs.oracle.com/javaee/7/tutorial/servlets.htm#BNAFD) 9 | -------------------------------------------------------------------------------- /kafka/docs/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | Apacke Kafka. 3 | 4 | ## Scheduler 5 | ### TODO 6 | - 启动过程 7 | - 消息的产生,结构等 8 | - 选举 9 | - 为啥会快呢?使用的数据结构? 10 | - ISR 11 | -------------------------------------------------------------------------------- /kafka/docs/developer_setup.md: -------------------------------------------------------------------------------- 1 | # Kafka 源码环境配置 2 | ## 环境配置 3 | - 安装 Scala 插件 4 | 过程:点击 Menu Item File | Settings -> Plugins -> Browse Repositories -> Search for Scala,安装。重启 IntelliJ 5 | - 创建 Kafka 分支 6 | 这里以 1.0 为例: 7 | ``` 8 | git clone git@github.com:apache/kafka.git 9 | cd kafka 10 | git checkout -b 1.0 remotes/origin/1.0 11 | ``` 12 | - 安装 Gradle 13 | 在 shell 中安装 Gradle。 14 | - 生成 Intellij 项目文件 15 | ``` 16 | cd 17 | gradle 18 | ./gradlew idea 19 | ``` 20 | 21 | ## 参考 22 | - [Developer Setup](https://cwiki.apache.org/confluence/display/KAFKA/Developer+Setup) 23 | -------------------------------------------------------------------------------- /kafka/docs/intro.md: -------------------------------------------------------------------------------- 1 | # Kafka简介 2 | 3 | 借[acmqueue](http://queue.acm.org/detail.cfm?id=1563874)的一张图,看下内存和磁盘的读取速度比较: 4 | 5 | ![内存和磁盘读取速度比较](../imgs/mem_vs_disk.jpg) 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /kafka/docs/jmx.md: -------------------------------------------------------------------------------- 1 | # Kafka 开启 JMX 2 | 其实很简单,编辑 `bin/kafka-server-start.sh` 脚本,查看是否有如下行: 3 | ``` 4 | export JMX_PORT=${JMX_PORT:-9999} 5 | ``` 6 | 7 | 即当 `JMX_PORT` 为 null 或空字符串时,该值为 9999,若需要调整为其他端口,只需要在该行前面给 JMX_PORT 赋值即可。添加完成后,保存退出,重启 Kafka 即可。 8 | 9 | 打开 jconsole,输入 `service:jmx:rmi:///jndi/rmi://:/jmxrmi`,如下图: 10 | 11 | ![connect](../imgs/jmx_1.jpg) 12 | 13 | ![info](../imgs/jmx_2.jpg) 14 | -------------------------------------------------------------------------------- /kafka/imgs/jmx_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kafka/imgs/jmx_1.jpg -------------------------------------------------------------------------------- /kafka/imgs/jmx_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kafka/imgs/jmx_2.jpg -------------------------------------------------------------------------------- /kafka/imgs/mem_vs_disk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kafka/imgs/mem_vs_disk.jpg -------------------------------------------------------------------------------- /kubernetes/README.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | ## C1 4 | - [Kubernetes 简介与安装](intro.md) 5 | - [Kubernetes 部署简单应用](deploy_app.md) 6 | - [Kubernetes 部署 GPU 应用](deploy_gpu.md) 7 | 8 | ## C2 9 | - [源码阅读前的准备](notes/1_prepare.md) 10 | - [kubectl](notes/2_kubectl.md) 11 | - [apiserver](notes/3_apiserver.md) 12 | - [scheduler](notes/4_scheduler.md) 13 | - [scheduler extender](notes/5_scheduler_extender.md) 14 | - [controller manager](notes/6_controller_manager.md) 15 | - [informer.md](notes/7_informer.md) 16 | - [device plugin](notes/8_device_plugin.md) 17 | -------------------------------------------------------------------------------- /kubernetes/etc/apiserver: -------------------------------------------------------------------------------- 1 | # /etc/kubernetes/apiserver 2 | # The address on the local server to listen to. 3 | KUBE_API_ADDRESS="--address=0.0.0.0" 4 | 5 | # The port on the local server to listen on. 6 | KUBE_API_PORT="--port=8080" 7 | 8 | # Port kubelets listen on 9 | KUBELET_PORT="--kubelet_port=10250" 10 | 11 | # Comma separated list of nodes in the etcd cluster 12 | KUBE_ETCD_SERVERS="--etcd_servers=http://127.0.0.1:2379" 13 | 14 | # Address range to use for services 15 | KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16" 16 | 17 | KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota" 18 | KUBE_API_ARGS="" 19 | -------------------------------------------------------------------------------- /kubernetes/etc/config: -------------------------------------------------------------------------------- 1 | # /etc/kubernetes/config 2 | # logging to stderr means we get it in the systemd journal 3 | KUBE_LOGTOSTDERR="--logtostderr=true" 4 | 5 | # journal message level, 0 is debug 6 | KUBE_LOG_LEVEL="--v=0" 7 | 8 | # Should this cluster be allowed to run privileged docker containers 9 | KUBE_ALLOW_PRIV="--allow-privileged=false" 10 | 11 | # How the replication controller and scheduler find the kube-apiserver 12 | KUBE_MASTER="--master=http://KUBE_MASTER:8080" 13 | -------------------------------------------------------------------------------- /kubernetes/etc/etcd.conf: -------------------------------------------------------------------------------- 1 | # /etc/etcd/etcd.conf 2 | # [member] 3 | ETCD_NAME=default 4 | ETC_DATA_DIR="/var/lib/etcd/default.etcd" 5 | ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" 6 | 7 | # [cluster] 8 | ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379" 9 | -------------------------------------------------------------------------------- /kubernetes/etc/flanneld: -------------------------------------------------------------------------------- 1 | # /etc/sysconfig/flanneld 2 | FLANNELD_ETCD_ENDPOINTS="http://KUBE_MASTER:2379" 3 | FLANNELD_ETCD_PREFIX="/kube/network" 4 | -------------------------------------------------------------------------------- /kubernetes/etc/kubelet: -------------------------------------------------------------------------------- 1 | # /etc/kubernetes/kubelet 2 | KUBELET_ADDRESS="--address=0.0.0.0" 3 | KUBELET_PORT="--port=10250" 4 | # 若 KUBELET_HOSTNAME 值为 "",则使用 Node 节点的 Hostname 做 Kubelet 的 Hostname。 5 | KUBELET_HOSTNAME="--hostname-override=NODE_HOSTNAME" 6 | KUBELET_API_SERVER="--api-servers=http://KUBE_MASTER:8080" 7 | -------------------------------------------------------------------------------- /kubernetes/etc/proxy: -------------------------------------------------------------------------------- 1 | # /etc/kubernetes/proxy 2 | KUBE_PROXY_ARGS="" 3 | -------------------------------------------------------------------------------- /kubernetes/img/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/img/.DS_Store -------------------------------------------------------------------------------- /kubernetes/img/arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/img/arch.png -------------------------------------------------------------------------------- /kubernetes/img/dashboard_overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/img/dashboard_overview.png -------------------------------------------------------------------------------- /kubernetes/img/redis_helloworld.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/img/redis_helloworld.png -------------------------------------------------------------------------------- /kubernetes/install.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | yum repo: 4 | ``` 5 | cat < /etc/yum.repos.d/kubernetes.repo 6 | [kubernetes] 7 | name=Kubernetes 8 | baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/ 9 | enabled=1 10 | gpgcheck=1 11 | repo_gpgcheck=1 12 | gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg 13 | EOF 14 | ``` 15 | 16 | - https://www.zybuluo.com/ncepuwanghui/note/953929 17 | - https://yq.aliyun.com/articles/626118 18 | -------------------------------------------------------------------------------- /kubernetes/install_by_kubeadm.md: -------------------------------------------------------------------------------- 1 | # 通过 kubeadm 安装 k8s 2 | 3 | ## 准备工作 4 | - 关闭 swap 5 | 执行 `swapoff -a` 并注释 `/etc/fstab` 中关于 swap 的行。 6 | 7 | 在 https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64/repodata/primary.xml 中,可以看到各版本 kubernetes 组件的下载地址。在一台能下载 rpm 包的机器上,下载 kubeadm, kubelet 等 rpm 包。 8 | 9 | -------------------------------------------------------------------------------- /kubernetes/iptables.md: -------------------------------------------------------------------------------- 1 | # iptables 详解 2 | 3 | CentOS 下 4 | -------------------------------------------------------------------------------- /kubernetes/k8s_in_action/README.md: -------------------------------------------------------------------------------- 1 | # Catalogue 2 | - [Kube Scheduler](kube_scheduler.md) 3 | -------------------------------------------------------------------------------- /kubernetes/k8s_in_action/cobra.md: -------------------------------------------------------------------------------- 1 | # Cobra 2 | 3 | Cobra is built on a structure of commands, arguments & flags. 4 | 5 | Commands represent actions, Args are things and Flags are modifiers for those actions. 6 | 7 | 8 | ## 参考 9 | - [cobra](https://github.com/spf13/cobra) 10 | - [Cobra简介](https://time-track.cn/cobra-brief-introduction.html) 11 | -------------------------------------------------------------------------------- /kubernetes/k8s_in_action/kube_scheduler.md: -------------------------------------------------------------------------------- 1 | # Kube-scheduler 2 | 3 | ## 作用 4 | 5 | ## 结构 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /kubernetes/notes/6_controller_manager.md: -------------------------------------------------------------------------------- 1 | # Controller Manager 2 | 3 | Controller Manager 是 Kubernetes 集群的管理控制中心,其主要负责 Node, Pod, Endpoint, Namespace 等的管理。Controller Manager 是一个控制循环,通过 apiserver 监视集群的共享状态,并通过更改操作尝试将当前状态变更为所需状态。 4 | 5 | 依然从 [cmd/kube-controller-manager/controller-manager.go](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/controller-manager.go) 开始分析。其调用 [NewControllerManagerCommand()](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L81) 生成 controller manager 的 command。 6 | 7 | 查看 command 的 [Run()](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L148),其主要做了如下事情: 8 | - 启动 HTTP 和/或 HTTPS 服务。 9 | - 调用 [https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L360](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L360) 设置 Controller,此方法设置了需要启动的 controller 类型。然后调用 [StartControllers](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L480) 启动设置的 controller。另外还可以看到,[NewControllerManagerCommand()](https://github.com/kubernetes/kubernetes/blob/release-1.13/cmd/kube-controller-manager/app/controllermanager.go#L102) 设置了默认不启动的 Controller:`bootstrapsigner` 和 `tokencleaner`。 10 | - 为启动的 controller manager 设置 ID(值为 `id + "_" + string(uuid.NewUUID())`)。 11 | - 进行 kube-controller-manager 的选主操作。 12 | -------------------------------------------------------------------------------- /kubernetes/notes/7_informer.md: -------------------------------------------------------------------------------- 1 | # Informer 2 | 3 | 4 | 5 | ## 参考 6 | - [Kubernetes Informer 详解](https://www.kubernetes.org.cn/2693.html) 7 | - [“高冷”的 Kubernetes Informer 一探究竟](https://caicloud.io/blog/5a1b83a975d69a0681e19584)) 8 | -------------------------------------------------------------------------------- /kubernetes/notes/client_go.md: -------------------------------------------------------------------------------- 1 | # client-go 2 | 3 | 4 | ## 参考 5 | - [client-go分享](https://v.qq.com/x/page/c03641vzw2m.html?start=7) 6 | -------------------------------------------------------------------------------- /kubernetes/notes/cni.md: -------------------------------------------------------------------------------- 1 | # CNI 2 | 3 | CNI(Container Network Interface)是 CNCF 旗下的一个项目,由一组配置容器网络接口的规范和库及一些插件组成。项目地址:[cni](https://github.com/containernetworking/cni)。 4 | 5 | 从项目文档中可以看到,CNI 的容器运行时包括:rkt, Kubernetes, Apache Mesos, Amazon EC2 等。常用的第三方插件实现有:Calico, Waeve, SR-IOV, DANM 等等。 6 | 7 | 当前 Kubernetes 1.13.0 使用的是 v0.6.0 的 CNI,所以这里以 v0.6.0 为例,说下 CNI 的大致结构。 8 | 9 | 10 | ## CNI 接口定义 11 | 查看 `libcni/api.go` 下的 CNI 接口定义,非常简单: 12 | 13 | ``` 14 | type CNI interface { 15 | AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error) 16 | DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) error 17 | 18 | AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error) 19 | DelNetwork(net *NetworkConfig, rt *RuntimeConf) error 20 | } 21 | ``` 22 | 23 | 该接口只有四个方法:添加网络、删除网络、添加网络列表、删除网络列表。 24 | 25 | 26 | ## CNI 插件 27 | CNI 项目组还维护了一系列实现 CNI 声明的相关[插件](https://github.com/containernetworking/plugins)。可以看到这些插件主要分为三大类: 28 | 29 | ### Main -- 创建接口 30 | - bridge:创建网桥,并添加主机和容器到该网桥。 31 | - ipvlan:在容器中添加一个 [ipvlan](https://www.kernel.org/doc/Documentation/networking/ipvlan.txt) 接口。 32 | - loopback:启动回环接口。 33 | - macvlan:创建新的 MAC 地址,将所有的流量转发给容器。 34 | - ptp: 创建veth 对。 35 | - vlan: 分配一个 vlan 设备。 36 | - host-device: 将已经存在的设置移动到容器。 37 | 38 | #### Windows 专用 39 | - win-bridge: 创建网桥,并添加主机和容器到该网桥。 40 | - win-overlay: 为容器创建 overlay 接口。 41 | 42 | ### IPAM -- 分配 IP 43 | - dhcp: 在主机上运行守护程序,代表容器发出 DHCP 请求。 44 | - host-local: 维护一个分配 IP 的本地数据库。 45 | - static: 为容器分配一个静态的 IPv4/IPv6 地址。 46 | 47 | ### Meta -- 其他插件 48 | - flannel: 根据flannel的配置文件创建接口。 49 | - tuning: Tweaks sysctl parameters of an existing interface 50 | - portmap: An iptables-based portmapping plugin. Maps ports from the host's address space to the container. 51 | - bandwidth: Allows bandwidth-limiting through use of traffic control tbf (ingress/egress). 52 | - sbr: A plugin that configures source based routing for an interface (from which it is chained). 53 | 54 | -------------------------------------------------------------------------------- /kubernetes/notes/extended_resource.md: -------------------------------------------------------------------------------- 1 | # Extended Resource 2 | 3 | ## 参考 4 | - [Advertise Extended Resources for a Node](https://kubernetes.io/docs/tasks/administer-cluster/extended-resource-node/) 5 | -------------------------------------------------------------------------------- /kubernetes/notes/img/device-plugin-overview.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/notes/img/device-plugin-overview.png -------------------------------------------------------------------------------- /kubernetes/notes/img/device-plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/notes/img/device-plugin.png -------------------------------------------------------------------------------- /kubernetes/notes/img/visitor-uml.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/kubernetes/notes/img/visitor-uml.png -------------------------------------------------------------------------------- /kubernetes/notes/network.md: -------------------------------------------------------------------------------- 1 | # Kubernetes 网络介绍 2 | 3 | ## 常用网络模型 4 | 5 | 6 | net/bridge/bridge-nf-call-iptables=1,开启 L3 的 iptables 过滤 L2 数据包的功能。 7 | 8 | - https://community.arm.com/tools/b/blog/posts/understanding-and-deploying-overlay-networks 9 | - https://medium.com/@jain.sm/flannel-vs-calico-a-battle-of-l2-vs-l3-based-networking-5a30cd0a3ebd 10 | - https://itnext.io/an-illustrated-guide-to-kubernetes-networking-part-1-d1ede3322727 11 | - https://itnext.io/an-illustrated-guide-to-kubernetes-networking-part-2-13fdc6c4e24c 12 | -------------------------------------------------------------------------------- /kubernetes/notes/ref.md: -------------------------------------------------------------------------------- 1 | # Ref 2 | 3 | - [design-proposals](https://github.com/kubernetes/community/tree/master/contributors/design-proposals) 4 | -------------------------------------------------------------------------------- /kubernetes/notes/service.md: -------------------------------------------------------------------------------- 1 | # Service 介绍 2 | 3 | Service 是一组 Pods 在逻辑上的抽象,并提供了对 Pods 的访问入口。Service 通常通过 Label Selector 来找到 Pod,此时会自动创建与 Service 同名的 Endpoints 并将数据 POST 给该 Endpoints。若不指定 Label Selector,则需要手动关联对应的 Endpoints。 4 | 5 | 对于 Kubernetes 原生应用,当 Service 中的 Pods 发生变化时,Kuberentes 会更新 Servcie 对应的 Endpoints 来感知变化。对于非原生应用,Kubernetes 为 Service 提供一个能直接访问后端 Pods 的虚拟 IP 网桥。 6 | 7 | ## 定义 Service 8 | 如下是一个典型的 Service 创建文件: 9 | 10 | ``` 11 | kind: Service 12 | apiVersion: v1 13 | metadata: 14 | name: my-service 15 | spec: 16 | selector: 17 | app: MyApp 18 | ports: 19 | - protocol: TCP 20 | port: 80 21 | targetPort: 9376 22 | nodePort: 300061 23 | ``` 24 | 25 | - port 是 Service 暴露的端口,其是提供给集群内部用户访问 Service 的入口。 26 | - nodePort 是启动在容器宿主机上的端口,其是 Kuberentes 提供给集群外部用户访问 Service 的一种入口。其他访问 Service 的方式会在下文叙述。 27 | - targetPort 是 Service 后的 pod 上的端口,从 port 和 nodePort 上进来的数据通过 kube-proxy 从 pod 的 targetPort 上进入容器。 28 | 29 | ## VIP 和 Service 代理 30 | Kubernetes 集群中的每个节点都会运行 `kube-proxy` 服务。`kube-proxy` 为 Service 提供 VIP 形式的实现。不同版本的 Kubernetes 中 kube-proxy 实现不同。在 Kubernetes v1.0 版本中,service 是 4 层概念,proxy 全在 userspace 中。而在 Kubernetes v1.1 中,引入了 Ingress 来代表 7 层服务,且增加了 iptables proxy。在 Kuberentes v1.8.0-beta.0 中,又添加了 ipvs proxy 代理。 31 | 32 | ### Proxy-mode: userspace 33 | 在这种模式下,kube-proxy 监听 Kubernetes Maser 对 `Service` 和 `Endpoints` 的添加和删除操作。对于每个 Service 对象,proxy 会在本地节点上随机选择一个 port,该代理端口上(serviceIP:port)的所有连接都会被 proxy 捕获,接着安装 iptables 规则用于转发给 Service 后端的 Pods。默认使用 round-robin 算法来选择 Pod。 34 | 35 | ![userspace](../img/services-userspace-overview.svg) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /kubernetes/systemd/docker.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Docker Application Container Engine 3 | Documentation=https://docs.docker.com 4 | After=network-online.target firewalld.service 5 | Wants=network-online.target 6 | 7 | [Service] 8 | Type=notify 9 | # 注意:需和 flanneld.service 中 mk-docker-opts.sh 生成的文件路径一致。 10 | EnvironmentFile=/run/flannel/docker 11 | ### 其他 Docker 启动参数可以在 /etc/sysconfig/docker 中配置 12 | # EnvironmentFile=-/etc/sysconfig/docker 13 | ### OPTIONS 在 /etc/sysconfig/docker 定义 14 | # ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS $OPTIONS 15 | ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS 16 | ExecReload=/bin/kill -s HUP $MAINPID 17 | # Having non-zero Limit*s causes performance problems due to accounting overhead 18 | # in the kernel. We recommend using cgroups to do container-local accounting. 19 | LimitNOFILE=infinity 20 | LimitNPROC=infinity 21 | LimitCORE=infinity 22 | # Uncomment TasksMax if your systemd version supports it. 23 | # Only systemd 226 and above support this version. 24 | #TasksMax=infinity 25 | TimeoutStartSec=0 26 | # set delegate yes so that systemd does not reset the cgroups of docker containers 27 | Delegate=yes 28 | # kill only the docker process, not all processes in the cgroup 29 | KillMode=process 30 | # restart the docker process if it exits prematurely 31 | Restart=on-failure 32 | StartLimitBurst=3 33 | StartLimitInterval=60s 34 | 35 | [Install] 36 | WantedBy=multi-user.target 37 | -------------------------------------------------------------------------------- /kubernetes/systemd/etcd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Etcd Server 3 | After=network.target 4 | 5 | [Service] 6 | Type=simple 7 | WorkingDirectory=/var/lib/etcd/ 8 | EnvironmentFile=/etc/etcd/etcd.conf 9 | ExecStart=/usr/bin/etcd 10 | 11 | [Install] 12 | WantedBy=multi-user.target 13 | -------------------------------------------------------------------------------- /kubernetes/systemd/flanneld.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Flanneld overlay address etcd agent 3 | After=network.target 4 | After=network-online.target 5 | Wants=network-online.target 6 | Before=docker.service 7 | 8 | [Service] 9 | Type=notify 10 | EnvironmentFile=/etc/sysconfig/flanneld 11 | EnvironmentFile=-/etc/sysconfig/docker-network 12 | ExecStart=/usr/bin/flanneld $FLANNEL_OPTIONS 13 | ExecStartPost=/usr/bin/mk-docker-opts.sh -k DOCKER_NETWORK_OPTIONS -d /run/flannel/docker 14 | Restart=on-failure 15 | 16 | [Install] 17 | WantedBy=multi-user.target 18 | RequiredBy=docker.service 19 | -------------------------------------------------------------------------------- /kubernetes/systemd/kube-apiserver.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes API Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=network.target 5 | After=etcd.service 6 | 7 | [Service] 8 | EnvironmentFile=-/etc/kubernetes/config 9 | EnvironmentFile=-/etc/kubernetes/apiserver 10 | User=kube 11 | ExecStart=/usr/bin/kube-apiserver \ 12 | $KUBE_LOGTOSTDERR \ 13 | $KUBE_LOG_LEVEL \ 14 | $KUBE_ETCD_SERVERS \ 15 | $KUBE_API_ADDRESS \ 16 | $KUBE_API_PORT \ 17 | $KUBELET_PORT \ 18 | $KUBE_ALLOW_PRIV \ 19 | $KUBE_SERVICE_ADDRESSES \ 20 | $KUBE_ADMISSION_CONTROL \ 21 | $KUBE_API_ARGS 22 | Restart=on-failure 23 | Type=notify 24 | LimitNOFILE=65536 25 | 26 | [Install] 27 | WantedBy=multi-user.target 28 | -------------------------------------------------------------------------------- /kubernetes/systemd/kube-controller-manager.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Controller Manager 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | 5 | [Service] 6 | EnvironmentFile=-/etc/kubernetes/config 7 | EnvironmentFile=-/etc/kubernetes/controller-manager 8 | User=kube 9 | ExecStart=/usr/bin/kube-controller-manager \ 10 | $KUBE_LOGTOSTDERR \ 11 | $KUBE_LOG_LEVEL \ 12 | $KUBE_MASTER \ 13 | $KUBE_CONTROLLER_MANAGER_ARGS 14 | Restart=on-failure 15 | LimitNOFILE=65536 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /kubernetes/systemd/kube-proxy.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Kube-Proxy Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=network.target 5 | 6 | [Service] 7 | EnvironmentFile=-/etc/kubernetes/config 8 | EnvironmentFile=-/etc/kubernetes/proxy 9 | ExecStart=/usr/bin/kube-proxy \ 10 | $KUBE_LOGTOSTDERR \ 11 | $KUBE_LOG_LEVEL \ 12 | $KUBE_MASTER \ 13 | $KUBE_PROXY_ARGS 14 | Restart=on-failure 15 | LimitNOFILE=65536 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /kubernetes/systemd/kube-scheduler.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Scheduler Plugin 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | 5 | [Service] 6 | EnvironmentFile=-/etc/kubernetes/config 7 | EnvironmentFile=-/etc/kubernetes/scheduler 8 | User=kube 9 | ExecStart=/usr/bin/kube-scheduler \ 10 | $KUBE_LOGTOSTDERR \ 11 | $KUBE_LOG_LEVEL \ 12 | $KUBE_MASTER \ 13 | $KUBE_SCHEDULER_ARGS 14 | Restart=on-failure 15 | LimitNOFILE=65536 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /kubernetes/systemd/kubelet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Kubelet Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=docker.service 5 | Requires=docker.service 6 | 7 | [Service] 8 | WorkingDirectory=/var/lib/kubelet 9 | EnvironmentFile=-/etc/kubernetes/config 10 | EnvironmentFile=-/etc/kubernetes/kubelet 11 | ExecStart=/usr/bin/kubelet \ 12 | $KUBE_LOGTOSTDERR \ 13 | $KUBE_LOG_LEVEL \ 14 | $KUBELET_API_SERVER \ 15 | $KUBELET_ADDRESS \ 16 | $KUBELET_PORT \ 17 | $KUBELET_HOSTNAME \ 18 | $KUBE_ALLOW_PRIV \ 19 | $KUBELET_ARGS 20 | Restart=on-failure 21 | KillMode=process 22 | 23 | [Install] 24 | WantedBy=multi-user.target 25 | -------------------------------------------------------------------------------- /ml/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | 一些计划和笔记。 4 | 5 | ## RoadMap 6 | 7 | ### 基础 8 | - 机器学习实战 9 | - [视频](https://space.bilibili.com/97678687/channel/detail?cid=22486) 10 | - [英文版 PDF](http://www2.ift.ulaval.ca/~chaib/IFT-4102-7025/public_html/Fichiers/Machine_Learning_in_Action.pdf) 11 | 12 | - 利用 python 进行数据分析 13 | 14 | - [机器学习速成课程 - 使用 TensorFlow API](https://developers.google.com/machine-learning/crash-course/) 15 | 16 | - 机器学习 17 | 18 | - 统计学习方法 19 | - [PDF](http://www.dgt-factory.com/uploads/2018/07/0725/%E7%BB%9F%E8%AE%A1%E5%AD%A6%E4%B9%A0%E6%96%B9%E6%B3%95.pdf) 20 | 21 | - Scikit-Learn 与 TensorFlow 机器学习实用指南 22 | 23 | - 神经网络 24 | - [playground](http://playground.tensorflow.org/) 25 | 26 | ### 资源 27 | - 云平台 28 | - [Colab](https://colab.research.google.com/notebooks/welcome.ipynb) 29 | - [Floydhub](https://www.floydhub.com/) 30 | - [Russell](https://russellcloud.com/) 31 | -------------------------------------------------------------------------------- /ml/distribute_train/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | - https://zhuanlan.zhihu.com/p/70312627 4 | - https://zhuanlan.zhihu.com/p/72939003 5 | - https://www.jiqizhixin.com/articles/2018-11-05-6 6 | -------------------------------------------------------------------------------- /ml/docs/README.md: -------------------------------------------------------------------------------- 1 | # 机器学习简易 2 | 3 | ## 数学相关 4 | - 最小二乘法 5 | - 导数(偏导,方向导数,梯度等) 6 | - 矩阵 7 | 8 | 9 | ## 分布式 10 | - https://zhuanlan.zhihu.com/p/79030485 11 | 12 | 13 | ## mpi 14 | - https://mpitutorial.com/tutorials/mpi-hello-world/zh_cn/ 15 | -------------------------------------------------------------------------------- /ml/docs/derivative.md: -------------------------------------------------------------------------------- 1 | # 导数 2 | 3 | ## 方向导数 4 | 多元函数的偏导数反映了函数值沿坐标轴方向的变化率,而许多实际问题 5 | 中常常还需要掌握函数在某点处沿某一指定方向的变化率。例如,为了预测某 6 | 地的风向和风力,必须掌握该地气压沿各个方向的变化率。这就引出了方向导 7 | 数的概念。 8 | 9 | 10 | 梯度即函数在某一点最大的方向导数,函数沿梯度方向函数有最大的变化率。 11 | - [ML重要概念](http://blog.csdn.net/walilk/article/details/50978864) 12 | - [方向导数、梯度](http://math.fudan.edu.cn/gdsx/KEJIAN/%E6%96%B9%E5%90%91%E5%AF%BC%E6%95%B0%E5%92%8C%E6%A2%AF%E5%BA%A6.pdf) 13 | - [方向导数与梯度](http://netedu.xauat.edu.cn/jpkc/netedu/jpkc/gdsx/homepage/5jxsd/51/513/5308/530807.htm) 14 | -------------------------------------------------------------------------------- /ml/docs/gd_vs_sgd.md: -------------------------------------------------------------------------------- 1 | # GD vs. SGD 2 | 3 | 梯度下降法的物理意义即沿着当前点的梯度方向进行 4 | -------------------------------------------------------------------------------- /ml/docs/king_county.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | - [Feature Ranking RFE, Random Forest, linear models](https://www.kaggle.com/arthurtok/feature-ranking-rfe-random-forest-linear-models) 4 | - [Predicting house prices in King County, Seattle](http://www.awesomestats.in/python-prediction-house-price/) 5 | - [Using Machine Learning to Predict Housing Prices Given Multivariate Input](https://web.stanford.edu/class/cs221/2017/restricted/p-final/ianjones/final.pdf) 6 | -------------------------------------------------------------------------------- /ml/docs/mpi/README.md: -------------------------------------------------------------------------------- 1 | # MPI 笔记 2 | 3 | 目的:大概了解 MPI 的相关知识。 4 | 5 | 6 | -------------------------------------------------------------------------------- /ml/docs/mpi/allgather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/allgather.png -------------------------------------------------------------------------------- /ml/docs/mpi/allreduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/allreduce.png -------------------------------------------------------------------------------- /ml/docs/mpi/barrier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/barrier.png -------------------------------------------------------------------------------- /ml/docs/mpi/broadcastvsscatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/broadcastvsscatter.png -------------------------------------------------------------------------------- /ml/docs/mpi/gather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/gather.png -------------------------------------------------------------------------------- /ml/docs/mpi/intro.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | MPI 是一系列并发计算架构的消息传输接口(Message Passing Interface)标准,其只是一个接口的标准定义,程序员需要根据不同架构去实现这个接口。 4 | 5 | ## MPI 对消息传递模型的定义 6 | MPI 在消息传递模型上的一些概念如下: 7 | - 通讯器(communicator) 8 | 通讯器定义了一组能够互相发消息的进程,在这组进程中,每个进程会被分配一个序号,称作秩(rank),进程间显性的通过秩来进行通信。 9 | - 点对点通信(point-to-point) 10 | 一个进程可以通过指定另一个进程的秩以及一个独一无二的消息标签来发送消息给另一个进程,接受者可以发送一个接收特定标签标记的消息的请求,然后依次处理接收到的数据。类似这样涉及一个发送者和一个接受者的通信被称作点对点通信。 11 | - 集体性(collective)通信 12 | 在很多情况下,某个进程可能需要跟其他所有进程通信,比如主进程想发一个广播给所有的从进程,在这种情况下,手写一个个进程点对点的信息传递会显得很笨拙,且会导致网络利用率低下。MPI 提供了专门的接口来处理这类所有进程间的集群性通信。 13 | 14 | ## 点对点通信 15 | 若进程 A 需要发送一些消息给进程 B,进程 A 会将需要发送的所有数据打包好,放在一个缓存里面。因为所有数据会被打包到一个大的信息里面,因此缓存常常被比作信封。数据打包进缓存之后,通信设备根据进程 B 的秩把数据传递组进程 B。数据发送给进程 B 后,进程 B 仍然需要确认它是否想接受进程 A 的数据。一旦 B 确认后,数据就被传输成功了。 16 | 17 | 有时 A 需要传递很多不同消息给 B,为了区分不同的消息,MPI 运行发送者和接受者额外的指定一些信息 tag,当 B 只要求接收某种特定 tag 的信息的时候,其他不是这个 tag 的信息会先被缓存起来,等到 B 需要的时候才发送给 B。 18 | 19 | 如下是 MPI 发送方法和接收方法的定义: 20 | 21 | ``` 22 | MPI_Send( 23 | void* data, 24 | int count, 25 | MPI_Datatype datatype, 26 | int destination, 27 | int tag, 28 | MPI_Comm communicator) 29 | 30 | MPI_Recv( 31 | void* data, 32 | int count, 33 | MPI_Datatype datatype, 34 | int source, 35 | int tag, 36 | MPI_Comm communicator, 37 | MPI_Status* status) 38 | ``` 39 | 40 | ## 集体通信 41 | 集体通信指的是一个涉及通信器里面所有进程的一个方法。关于集体通信需记住的一点是它在进程间引入了同步点的概念,意味着所有的进程在执行代码时候必须先到达一个同步点才能执行后面的代码。MPI 有一个特殊的函数来做同步进程的这个操作:`MPI_Barrier(MPI_Comm communicator)`,这个方法会构建一个屏障(Barrier),任何进程都没法跨越屏障,直到所有的进程都到达屏障,如下示意图(水平轴代表的是程序的执行过程,小圆圈代表不同的进程): 42 | 43 | ![barrier](barrier.png) 44 | 45 | 进程 0 在时间点 (T 1) 首先调用 MPI_Barrier。然后进程 0 就一直等在屏障之前,之后进程 1 和进程 3 在 (T 2) 时间点到达屏障。当进程 2 最终在时间点 (T 3) 到达屏障的时候,其他的进程就可以在 (T 4) 时间点再次开始运行。 46 | 47 | `MPI_Barrier` 在很多时候很有用,比如同步一个程序,使用的分布式代码中的某一部分可以被精确的计时。关于同步有个需要注意的地方即:始终记得每一个你调用的集体通信方法都是同步的。 48 | 49 | ### 广播 50 | 广播是标准的集体通信技术之一。一个广播发生的时候,一个进程会把同样一份数据传递给一个 communicator 里面的所有其他进程。广播的主要用途之一是把用户输入传递给一个分布式程序,或者把一些配置参数传递给所有的进程。 51 | 52 | 在 MPI 中,广播可以使用 `MPI_Bcast` 来做到,函数签名看起来如下: 53 | ``` 54 | MPI_Bcast( 55 | void* data, 56 | int count, 57 | MPI_Datatype datatype, 58 | int root, 59 | MPI_Comm communicator) 60 | ``` 61 | 62 | ### MPI_Scatter、MPI_Gather 和 MPI_Allgather 63 | `MPI_Scatter` 是一个跟 `MPI_Bcast` 类似的集体通信机制,其将根进程的数据发送给 communicator 中所有进程,区别是 `MPI_Bcast` 给每个进程发送的是同样的数据,然而 `MPI_Scatter` 给每个进程发送的部分数据。 64 | 65 | ![bcast_vs_scatter](broadcastvsscatter.png) 66 | 67 | `MPI_Gather` 跟 `MPI_Scatter` 作用是相反的,其从若干个进程中收集数据到一个进程上面,如下是其示意图: 68 | 69 | ![gather](gather.png) 70 | 71 | `MPI_Scatter` 和 `MPI_Gather` 用来操作多对一或一对多的通信模式,对于多对多的通信模式,可以使用 `MPI_Allgather`。对于分发在所有进程上的一组数据来说,`MPI_Allgather` 会收集所有数据到所有进程上,即其相当于在一个 `MPI_Gather` 操作后跟一个 `MPI_Bcast` 操作,如下示意图: 72 | 73 | ![mpi_allgather](allgather.png) 74 | 75 | ### MPI_Reduce 和 MPI_Allreduce 76 | 77 | reduce 是函数式编程中的一个基础概念,通过一个函数,其将一组数据缩减为更少一组数据,如对于数组 `[1, 2, 3, 4, 5]`,通过调用 `sum` 方法,最后结论为一个数字 15。`MPI_Reduce` 的作用即如此,其示意图如下: 78 | 79 | ![mpi_reduce](reduce.png) 80 | 81 | 82 | 类似于 `MPI_Allgather` 将数据发送给一组进程,`MPI_Allreduce` 也是将所有数据发给所有进程: 83 | 84 | ![mpi_allreduce](allreduce.png) 85 | 86 | 87 | 88 | ## 参考 89 | - [Message Passing Interface](https://en.wikipedia.org/wiki/Message_Passing_Interface) 90 | -------------------------------------------------------------------------------- /ml/docs/mpi/reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/docs/mpi/reduce.png -------------------------------------------------------------------------------- /ml/gpu/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | - GPU 的组成结构,通信方式,常用命令 4 | - kubernetes 如何感知 GPU 的拓扑 --> A Kubernetes-based Scheduler Framework 5 | - GPU 的虚拟化,挑战,优缺点 --> https://cloud.tencent.com/developer/article/1389547 6 | 7 | ## GPU 虚拟化 8 | - https://caicloud.io/blog/5cd8e472275dbb002b9cd5b6 9 | - https://blog.spider.im/post/gpu-share-in-k8s/ 10 | 11 | 12 | ## TOREAD 13 | - https://www.infoq.cn/article/3D4MsRVS8ZOtGCj7*krT 14 | - https://yq.aliyun.com/articles/591403 15 | - https://yq.aliyun.com/articles/599656 16 | 17 | ## GPU arch 18 | 19 | - http://www.mat.unimi.it/users/sansotte/cuda/CUDA_by_Example.pdf 20 | - https://www.cs.cmu.edu/afs/cs/academic/class/15462-f11/www/lec_slides/lec19.pdf 21 | - http://www.eziobartocci.com/intro_1.pdf 22 | - https://courses.cs.washington.edu/courses/cse471/13sp/lectures/GPUsStudents.pdf 23 | - https://www.datascience.com/blog/cpu-gpu-machine-learning 24 | - http://cdn.iiit.ac.in/cdn/cstar.iiit.ac.in/~kkishore/GPUArchitecture.pdf 25 | - http://haifux.org/lectures/267/Introduction-to-GPUs.pdf 26 | - https://hustcat.github.io/gpu-architecture/ 27 | 28 | ## 分布式训练 29 | - [一文说清楚Tensorflow分布式训练必备知识](https://zhuanlan.zhihu.com/p/56991108) 30 | - https://mp.weixin.qq.com/s?__biz=MzA3MzI4MjgzMw==&mid=2650745993&idx=2&sn=a7cbba27e46a68588d7eb5084201717c&chksm=871ae8f7b06d61e19debfbd288a1220a643888cbba7a7e66112b988577223da44bfaae76dd79&scene=21#wechat_redirect 31 | 32 | ## 框架 33 | - paddlepaddle 34 | - [horovod](https://github.com/horovod/horovod) 35 | - [byteps](https://github.com/bytedance/byteps) 36 | -------------------------------------------------------------------------------- /ml/gpu/gpu.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 参考 4 | - [NVIDIA GPUDirect](https://developer.nvidia.com/gpudirect) 5 | - [浅析GPU通信技术(上)-GPUDirect P2P](https://yq.aliyun.com/articles/591403) 6 | -------------------------------------------------------------------------------- /ml/gpu/imgs/deep-learning-nvlink-performance-chart-625-udt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/deep-learning-nvlink-performance-chart-625-udt.png -------------------------------------------------------------------------------- /ml/gpu/imgs/gpu-direct-rdma-over-infiniband-with-and-without.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/gpu-direct-rdma-over-infiniband-with-and-without.png -------------------------------------------------------------------------------- /ml/gpu/imgs/multi-gpu-cpu-parameter-server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/multi-gpu-cpu-parameter-server.png -------------------------------------------------------------------------------- /ml/gpu/imgs/multi-gpu-multi-gpu-all_reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/multi-gpu-multi-gpu-all_reduce.png -------------------------------------------------------------------------------- /ml/gpu/imgs/multi-node-all_reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/multi-node-all_reduce.png -------------------------------------------------------------------------------- /ml/gpu/imgs/multi-node-asynchronous-distributed-sgd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/multi-node-asynchronous-distributed-sgd.png -------------------------------------------------------------------------------- /ml/gpu/imgs/multiple-parameter-servers-distributed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/multiple-parameter-servers-distributed.png -------------------------------------------------------------------------------- /ml/gpu/imgs/nvidia-nvswitch-diagram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/nvidia-nvswitch-diagram.jpg -------------------------------------------------------------------------------- /ml/gpu/imgs/pci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/pci.png -------------------------------------------------------------------------------- /ml/gpu/imgs/pcie-bandwidth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/pcie-bandwidth.png -------------------------------------------------------------------------------- /ml/gpu/imgs/pcie-topology.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/pcie-topology.jpg -------------------------------------------------------------------------------- /ml/gpu/imgs/pcie-vs-pci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/pcie-vs-pci.png -------------------------------------------------------------------------------- /ml/gpu/imgs/ring-all_reduce-distributed-training.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/ring-all_reduce-distributed-training.png -------------------------------------------------------------------------------- /ml/gpu/imgs/single-gpu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/single-gpu.png -------------------------------------------------------------------------------- /ml/gpu/imgs/synchronous-distributed-sgd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/synchronous-distributed-sgd.png -------------------------------------------------------------------------------- /ml/gpu/imgs/tesla-v100-nvlink-gpu-cpu-diagram-625-udt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/tesla-v100-nvlink-gpu-cpu-diagram-625-udt.png -------------------------------------------------------------------------------- /ml/gpu/imgs/tesla-v100-nvlink-hybrid-cube-mesh-diagram-625-udt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/gpu/imgs/tesla-v100-nvlink-hybrid-cube-mesh-diagram-625-udt.png -------------------------------------------------------------------------------- /ml/gpu/multi_gpu_and_multi_node_training.md: -------------------------------------------------------------------------------- 1 | # 分布式训练方案 2 | 3 | ## 类型 4 | 分布式训练有如下几种类型: 5 | 6 | ### Single GPU 7 | 8 | ![single cpu](imgs/single-gpu.png) 9 | 10 | - 计算位置:单个 GPU 上 11 | - 梯度传递:N/A 12 | - 模型传递:N/A 13 | 14 | ### Multi GPU Training (CPU Parameter Server) 15 | 16 | ![multi gpu cpu ps](imgs/multi-gpu-cpu-parameter-server.png) 17 | 18 | - 计算位置:CPU 和所有 GPU 上 19 | - 梯度传递:从 GPU 到 CPU (reduce) 20 | - 模型传递:从 CPU 到 GPU (BROADCAST) 21 | 22 | ### Multi GPU Training (Multi GPU all-reduce) 23 | 24 | ![multi gpu all-reduce](imgs/multi-gpu-multi-gpu-all_reduce.png) 25 | 26 | - 计算位置:所有 GPU 27 | - 梯度传递:在 NCCL all-reduce 期间从 GPU 到 GPU 28 | - 模型传递:在 NCCL all-reduce 期间从 GPU 到 GPU 29 | 30 | ### Asynchronous Distributed SGD 31 | 32 | ![asyn distributed SGD](imgs/multi-node-asynchronous-distributed-sgd.png) 33 | 34 | - 计算位置:所有 worker 和 parameters 服务器 35 | - 梯度传递:从 worker 服务器异步到 parameter 服务器 36 | - 模型传递:从 parameter 服务器异步到 worker 服务器 37 | 38 | ### Synchronous Distributed SGD 39 | 40 | ![syn distributed SGD](imgs/synchronous-distributed-sgd.png) 41 | 42 | - 计算位置:所有 worker 和 parameters 服务器 43 | - 梯度传递:从 worker 服务器到 parameter 服务器 44 | - 模型传递:从 parameter 服务器到 worker 服务器 45 | 46 | ### Multiple Parameter Servers 47 | 48 | ![multiple ps](imgs/multiple-parameter-servers-distributed.png) 49 | 50 | - 计算位置:所有 worker 和 parameters 服务器 51 | - 梯度传递:worker 梯度分片给 parameter 服务器 52 | - 模型传递:parameter 服务器的模型分片给 worker 服务器 53 | 54 | ### Ring all-reduce Distributed Training 55 | 56 | ![ring all reduce distributed training](imgs/ring-all_reduce-distributed-training.png) 57 | 58 | 59 | - 计算位置:所有 worker 服务器 60 | - 梯度传递:all-reduce 期间 worker 服务器传输梯度给对应的节点 61 | - 模型传递:多节点 all-reduce 操作结束后执行模型“更新” 62 | 63 | 64 | 65 | 66 | 67 | ## 参考 68 | - [Distributed Training: A Gentle Introduction](https://lambdalabs-files.s3-us-west-2.amazonaws.com/lambdalabs.com_presents_distributed-training-a-gentle-introduction.pdf) 69 | -------------------------------------------------------------------------------- /ml/ml-zzh/README.md: -------------------------------------------------------------------------------- 1 | 周志华老师《机器学习》的阅读笔记。 2 | 3 | 数据知识TODO: 4 | - 最小二乘法 5 | - 梯度下降 6 | -------------------------------------------------------------------------------- /ml/ml-zzh/chapter01-basic.md: -------------------------------------------------------------------------------- 1 | # 绪论 2 | ## 基本术语 3 | 4 | 机器学习致力于通过计算手段,利用经验(即已有数据)来改善自身的性能。机器学习研究的主要内容是从数据中产生“模型”算法,即学习算法。 5 | 6 | 术语 | 解释 | 例子 7 | ------|------|------- 8 | 样本(sample )/示例(instance)/特征向量(feature vector)| 一个事件或对象 | 西瓜 9 | 数据集 样本的集合 | 若干个西瓜 10 | 特征(feature)/属性(attribute) | 事件或对象在某方面的性质 | 西瓜的“色泽”,“根蒂”,“敲声” 等 11 | 属性值 | 属性的取值 | “色泽”为“青绿”,“根蒂”为“蜷缩” 12 | 属性空间/样本空间/输入空间 | 各属性组成的空间 | 将 “色泽”,“根蒂”,“敲声”作为三个坐标轴,它们即组成一个用于描述西瓜的三维空间。 13 | 维数 | 属性的数目 | 如“色泽”,“根蒂”,“敲声”这三个属性用以描述西瓜成熟度,则维数为 3。 14 | 学习(learning)或训练(training)| 通过某个算法从数据中学得模型。 | 15 | 训练数据 | 训练过程中使用的数据 | 16 | 训练样本 | 训练数据中的每个样本 | 17 | 训练集 | 训练样本组成的集合| 18 | 标记(label) | 关于样本的信息 | 如将“色泽”为“青绿”,“根蒂”为蜷缩,“敲声”为浑浊的西瓜标记为好瓜。 19 | 样例(example)| 拥有标记信息的样本 | 20 | 标记空间/输出空间 | 所有标记的集合 | 21 | 分类 | 预测类型是离散值 | 如“好瓜”、“坏瓜”。 22 | 回归 | 预测类型是连续值 | 如西瓜的成熟度。 23 | 二分类 | 只涉及两个类型的分类,通过称其中一个分类为“正类”,另外一个为“反类” | 如“好瓜”,“坏瓜” 24 | 多分类 | 涉及多个类型的分类 | 25 | 测试 | 学得模型后,使用该模型进行预测的过程 | 26 | 测试样本 | 用于测试的样本 | 27 | 聚类 | 将训练集中的样本集分成若干组,每组称为一个“簇”(cluster) | 28 | 监督学习(supervised learning) | 训练数据有标记信息 | 代表:分类和回归 29 | 无监督学习(unsupervised learning)| 训练数据无标记信息 | 代表:聚类 30 | 泛化(generalization) | 模型适用于新样本的能力 | 31 | 假设 | 训练后的结果,即学得模型 | 如好瓜的假设 =(“色泽”= * )^ (“根蒂”=蜷缩)^ (“敲声”= * ) 32 | 假设空间 | 所有可能假设组成的空间 | 如好瓜的假设 =(“色泽”= * )^ (“根蒂”= * )^ (“敲声”= * ) 33 | 34 | 35 | ## 归纳偏好 36 | 37 | 一般而言,通过学习可能产生多个与训练集一致的假设,但它们在面对新样本时,会产生不同的输出。如图: 38 | 39 | ![图01-01](image/01_01.png) 40 | 41 | 任何一个有效的机器学习算法必有其归纳偏好。那么有没有一般性的原则来引导算法建立“正确的”的偏好呢?“奥卡姆剃刀”(Occam's razor)是一种常用的、自然科学研究中最基本的科学,即**若有多个假设与观察一致,则选最简单的那个**。 42 | 43 | 然而,“奥卡姆剃刀”并非唯一可行的原则,对于一个学习算法 A,若在某些问题上比学习算法 B 好,则必然存在另外一些问题,使得算法 B 要好于算法 A。不过很多时候我们只关注自己正在试图解决的问题,对于这个问题的解决方案,我们不关心该解决方案在别的相似的问题上是否为好方案。所以在谈论算法优劣时,必须针对具体的学习问题,学习算法自身的归纳偏好与问题是否相配,往往起到决定性的作用。 44 | 45 | -------------------------------------------------------------------------------- /ml/ml-zzh/chapter02-model-evaluation.md: -------------------------------------------------------------------------------- 1 | # 模型评估与选择 2 | 3 | -------------------------------------------------------------------------------- /ml/ml-zzh/chapter05-neural-networks.md: -------------------------------------------------------------------------------- 1 | # 神经网络 2 | 3 | 4 | -------------------------------------------------------------------------------- /ml/ml-zzh/image/01_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/ml-zzh/image/01_01.png -------------------------------------------------------------------------------- /ml/nccl/img/allgather.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/nccl/img/allgather.png -------------------------------------------------------------------------------- /ml/nccl/img/allreduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/nccl/img/allreduce.png -------------------------------------------------------------------------------- /ml/nccl/img/broadcast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/nccl/img/broadcast.png -------------------------------------------------------------------------------- /ml/nccl/img/reduce.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/nccl/img/reduce.png -------------------------------------------------------------------------------- /ml/nccl/img/reducescatter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/ml/nccl/img/reducescatter.png -------------------------------------------------------------------------------- /monitor/README.md: -------------------------------------------------------------------------------- 1 | # README 2 | 3 | 关于监控相关的监控项及Ganglia说明。 4 | 5 | ## 目录 6 | - [Linux基础监控项说明](linux_metrics.md) 7 | - [Hadoop监控项说明](hadoop_metrics.md) 8 | - [工具说明](tools.md) 9 | - [Ganglia安装及配置说明](install_ganglia.md) 10 | -------------------------------------------------------------------------------- /monitor/cdh_monitor.md: -------------------------------------------------------------------------------- 1 | cdh相关api。 2 | 3 | 4 | 根据role重启实例: 5 | 6 | ``` 7 | # curl -X POST -H "Content-Type:application/json" -u admin:admin -d '{"items" : ["yarn-NODEMANAGER-a534b2ce0c27c39b2fc904ab550dd0d5"]}' 'http://xbd01-004:7180/api/v12/clusters/testCluster/services/yarn/roleCommands/restart' 8 | ``` 9 | 返回结果如下: 10 | ``` 11 | { 12 | "errors" : [ ], 13 | "items" : [ { 14 | "id" : 620, 15 | "name" : "Restart", 16 | "startTime" : "2016-07-25T11:35:22.633Z", 17 | "active" : true, 18 | "serviceRef" : { 19 | "clusterName" : "cluster", 20 | "serviceName" : "yarn" 21 | }, 22 | "roleRef" : { 23 | "clusterName" : "cluster", 24 | "serviceName" : "yarn", 25 | "roleName" : "yarn-NODEMANAGER-a534b2ce0c27c39b2fc904ab550dd0d5" 26 | } 27 | } ] 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /monitor/linux_metrics.md: -------------------------------------------------------------------------------- 1 | # Linux Server监控项 2 | 3 | 监控做为基础服务,对问题发现和日常排错起到很好的作用。对于各种应用而言,精准正确的监控显得格外重要。一般而言,应该监控哪些项呢? 4 | 5 | ## CPU 6 | ### 上下文切换 7 | 在监控Linux应用时,当CPU利用率很高时,系统性能仍然上不去的话,可以看下是否由于上下文切换过于频繁。若确实上下文切换频繁,可通过[latencytop](http://blog.yufeng.info/archives/1239)或者pidstat来查看由哪些进程引起的。 8 | 9 | ### 中断 10 | 中断分为硬中断和软中断。频繁的中断会消耗一些cpu资源,通常而言中断默认集中在cpu0上(通过`cat /proc/interrupts`查看),一旦系统繁忙,该cpu会成为瓶颈。在SMP架构中,可通过其affinity技术将信号分散到不同的cpu上。 11 | 12 | ### 运行队列 13 | 当内核要寻找新进程在cpu上执行时,只能考虑处于可运行状态的进程,由于扫描整个进程列表相当低效,所以引入了可运行状态进程的双向循环链表,也叫运行队列。正在运行的进程数加运行队列的长度(即等待cpu的进程数),即平时所说的load。load反映了CPU的负载情况。 14 | 15 | ### CPU使用率 16 | CPU使用率有如下7种情况: 17 | - idle 18 | 闲置cpu时间百分比。 19 | user 20 | 用户使用的cpu时间百分比。 21 | - system 22 | 系统使用的cpu时间百分比。 23 | - nice 24 | 改变过优先级的进程使用的CPU时间百分比。 25 | - iowait 26 | 等待io完成使用的cpu时间百分比。 27 | - irq 28 | 响应硬中断使用的cpu时间百分比。 29 | - softirq 30 | 响应软中断使用的cpu时间百分比。 31 | 32 | 通过读取`/proc/stat`等文件可查看cpu运行情况,/proc/stat说明见[这里](http://www.linuxhowtos.org/System/procstat.htm)。也可通过其他如vmstat, dstat, sar等查看。top命令中,%wa高,说明磁盘忙;%si高,说明软中断多。 33 | 34 | ## Memory 35 | 内存主要分为实际物理内存和swap两部分,内存监控项如下: 36 | 37 | - 总内存大小 38 | - 已使用内存大小 39 | - buffer 40 | - cache 41 | - free 42 | - 可用内存大小 43 | - 总swap大小 44 | - 使用swap大小 45 | - swap in 46 | - swap out 47 | - 内存条是否损坏 48 | 49 | 参过free或vmstat可监控得到。 50 | 51 | ## Disk 52 | ### 磁盘使用率 53 | 包括如下监控项: 54 | 55 | - 每块盘总大小 56 | - 每块盘已使用量 57 | - 每块盘可用量 58 | 59 | 通过df可查看。 60 | 61 | ### I/O 62 | - 每秒I/O次数 63 | - I/O rate,即每秒读写吞吐量 64 | - io util 65 | - I/O请求队列长度 66 | - 磁盘服务时间,即磁盘读写操作执行的时间,包括寻道,旋转数据传输时间。 67 | - io wait,磁盘读写等待时间,即在队列中排除的时间 68 | 69 | 通过iostat和sar查看。另外,可自行计算IOPS。 70 | 71 | ### inode 72 | 包括如下项: 73 | 74 | - inode总数 75 | - 已使用inode数 76 | - inode可用数 77 | 78 | 通过`df -i`可以看到各盘的inode情况。 79 | 80 | ### 磁盘是否损坏 81 | megacli或SMART监控。Raid阵列是否有问题。 82 | 83 | ## Network 84 | 各网口的网络监控项如下: 85 | - byte sent 86 | - byte recv 87 | - packets sent 88 | - packets recv 89 | - dropped packets sent 90 | - dropped packets recv 91 | - frame alignment errors sent 92 | - frame alignment errors recv 93 | 94 | 可通过[Linux Network Statistics Tools / Commands](http://www.cyberciti.biz/faq/network-statistics-tools-rhel-centos-debian-linux/)来查看。 95 | 96 | ## Task 97 | ### 进程数 98 | 当前总的进程数,运行队列中的进程数,等待中的进程数,Sleep进程数。 99 | 100 | ## PageCache 101 | 对于Kafka服务,还需要PageCache的情况,详见Kafka监控项。 102 | 103 | ## 服务监控 104 | - ntp 105 | - nfs 106 | - httpd 107 | - mysqld 108 | - nginx 109 | - redis 110 | 111 | 服务的监控可监控其对应的端口。 112 | 113 | ## 其他 114 | - 机器重启 115 | - 机器关机 116 | - 其他不太重要项如CPU风扇转速,CPU温度,磁盘温度的监控。 117 | 118 | 针对上述监控,也可通过python中的[psutil模块](https://pythonhosted.org/psutil/)来统一获得。 119 | 120 | ## Reference 121 | - [linux-performance-monitoring-intro](http://www.thegeekstuff.com/2011/03/linux-performance-monitoring-intro/) 122 | - [Monitoring HPC Systems: Processor and Memory Metrics](http://www.admin-magazine.com/HPC/Articles/Processor-and-Memory-Metrics) 123 | - [Monitoring HPC Systems: Process, Network, and Disk Metrics](http://www.admin-magazine.com/HPC/Articles/Process-Network-and-Disk-Metrics) 124 | 125 | -------------------------------------------------------------------------------- /monitor/metrics2.md: -------------------------------------------------------------------------------- 1 | # Metrics2说明 2 | 3 | 语法如下: 4 | ``` 5 | [prefix].[source|sink|jmx|].[instance].[option] 6 | ``` 7 | 8 | 9 | ## 参考: 10 | - [Package org.apache.hadoop.metrics2](https://hadoop.apache.org/docs/r2.7.2/api/org/apache/hadoop/metrics2/package-summary.html) 11 | - [Hadoop metrics filtering](http://blog.shmuma.ru/2014/10/31/hadoop-metrics-filtering/) 12 | - [ganglia收集hbase的metrics](http://blog.csdn.net/k_james/article/details/38117873) 13 | - [hbase metrics](http://hbase.apache.org/book.html#hbase_metrics) 14 | - [HADOOP-6728-MetricsV2](http://wiki.apache.org/hadoop/HADOOP-6728-MetricsV2) 15 | 16 | -------------------------------------------------------------------------------- /monitor/tools.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/monitor/tools.md -------------------------------------------------------------------------------- /oozie/enable_oozie_web_console.md: -------------------------------------------------------------------------------- 1 | #Enable Oozie Server Web Console 2 | 3 | 4 | 过程如下: 5 | - 下载[ext-2.2.zip](http://dev.sencha.com/deploy/ext-2.2.zip)。 6 | - 将ext-2.2.zip解压到`/var/lib/oozie`目录中,即`/var/lib/oozie/ext-2.2`。 7 | - CDH的oozie的configuration中,勾选`Enable Oozie Server Web Console`。 8 | 9 | **UPDATE: ext-2.2已在oozie中存在,路径:/var/lib/oozie/tomcat-deployment/webapps/oozie。即做个软链即可。** 10 | 11 | 然后刷新oozie web页面即可。 12 | 13 | 14 | -------------------------------------------------------------------------------- /ref.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | 一些大数据相关且个人觉得不错的内容。欢迎补充~ 3 | 4 | ## Catalog 5 | ### Blog 6 | - [Apache Blog](https://blogs.apache.org/) 7 | - [Cloudera Blog](http://blog.cloudera.com/) 8 | - [有态度的HBase](http://hbasefly.com/):专注于 HBase, Spark 等。 9 | - [Hbase Musings](http://blog.zahoor.in/):内容不多且几年未更新了,但质量不错。 10 | - [Machine Learning for Humans](https://medium.com/machine-learning-for-humans): ML 11 | 12 | ### Github 13 | - Spark 14 | - [SparkInternals](https://github.com/JerryLead/SparkInternals) : JerryLead 15 | - Deep Learning 16 | - [deeplearningbook-chinese](https://github.com/exacity/deeplearningbook-chinese) 17 | 18 | ### Article 19 | - Distributed System 20 | - [Distributed systems theory for the distributed systems engineer](http://the-paper-trail.org/blog/distributed-systems-theory-for-the-distributed-systems-engineer/) 21 | 22 | ### Page 23 | - [Bigtable: A Distributed Storage System for Structured Data](https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf) 24 | - [Google Bigtable 中文版](http://blog.bizcloudsoft.com/wp-content/uploads/Google-Bigtable%E4%B8%AD%E6%96%87%E7%89%88_1.0.pdf) 25 | 26 | ### Book 27 | TODO 28 | -------------------------------------------------------------------------------- /scala/docs/语法.md: -------------------------------------------------------------------------------- 1 | # 语法 2 | 3 | ## 查看对象类型 4 | 通过`obj.isInstanceOf[T]`来判断,ojb为对象,T为检测类型。 5 | 6 | 7 | -------------------------------------------------------------------------------- /scala/imgs/setting-expression.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/scala/imgs/setting-expression.png -------------------------------------------------------------------------------- /solr/README.md: -------------------------------------------------------------------------------- 1 | solr可用于HDFS和HBase等的近实时搜索,同时可用于HBase的二级索引。[Cloudera](http://www.cloudera.com/documentation/enterprise/latest/topics/search.html)采用solr作用其搜索组件。 2 | -------------------------------------------------------------------------------- /spark/README.md: -------------------------------------------------------------------------------- 1 | # Spark 2 | - [Spark 安装](spark_install.md) 3 | - [Spark 速览](spark_guide.md) 4 | 5 | ## to read 6 | 7 | - stage codegen 8 | - verctorized query execution 9 | - predicate pushdown, Column Pruning, Constant Folding 10 | - shuffle 11 | - broadcast hash join, shuffle hash join, sort merge join (CBO) 12 | - textfile, sequencefile, avro, parquet, orc 13 | - https://www.slideshare.net/StampedeCon/choosing-an-hdfs-data-storage-format-avro-vs-parquet-and-more-stampedecon-2015 14 | - https://spoddutur.github.io/spark-notes/deep_dive_into_storage_formats.html 15 | 16 | - http://datastrophic.io/core-concepts-architecture-and-internals-of-apache-spark/ 17 | -------------------------------------------------------------------------------- /spark/submit_python_script.md: -------------------------------------------------------------------------------- 1 | # Spark 提交 python 脚本 2 | 3 | 提交 python 脚本时,可能报错:`ImportError: No module name xxxx`。 4 | 5 | 解决方法: 6 | 正确生成 zip 的方法: 7 | ``` 8 | $ cd my-folder 9 | $ zip -r ../my-folder.zip . 10 | ``` 11 | 这样 spark 在解压时,需要的文件会出现在解压目录第一层(即 my-folder 下各文件直接出现在 spark 解压目录下,而不是 my-folder 目录中)。 12 | 13 | 如下做法是错误的: 14 | ``` 15 | $ zip -r my-folder.zip my-folder/* 16 | ``` 17 | 18 | 或在代码中将文件加到 `SparkContext` 中,如下: 19 | ``` 20 | sc.addPyFile(file_path) 21 | ``` 22 | 23 | 说明:--py-files 和 --archives 等区别。 24 | 25 | ## 参考 26 | - [How-to: Prepare Your Apache Hadoop Cluster for PySpark Jobs](https://blog.cloudera.com/blog/2015/09/how-to-prepare-your-apache-hadoop-cluster-for-pyspark-jobs/) 27 | - [在spark上运行Python脚本遇到“ImportError: No module name xxxx”](https://blog.csdn.net/wangxiao7474/article/details/81391300) 28 | - [I can't seem to get --py-files on Spark to work](https://stackoverflow.com/questions/36461054/i-cant-seem-to-get-py-files-on-spark-to-work) 29 | - [PySpark dependencies](http://blog.danielcorin.com/code/2015/11/10/pyspark.html) 30 | - [Hadoop DistributedCache详解](http://dongxicheng.org/mapreduce-nextgen/hadoop-distributedcache-details/) 31 | -------------------------------------------------------------------------------- /spring/1_intro.md: -------------------------------------------------------------------------------- 1 | # Spring Introduce 2 | 3 | ## IoC 简介 4 | 所有的被注入对象和依赖对象由 IoC Service Provider 统一管理。被注入对象通过如下方式通知 IoC Service Provider 为其提供服务: 5 | - 构造方法注入 6 | 优点是对象在构造完成之后即可使用,缺点是依赖对象较多时,构造方法的参数列表比较长。而且在 Java 中,构造方法无法被继承,无法设置默认值。 7 | - setter方法注入 8 | 因为方法可以命名,所以setter方法注入在描述性上要比构造方法注入好一些。 另外,setter方法可以被继承,允许设置默认值,而且有良好的IDE支持。缺点当然就是对象无法在构造完成后马上进入就绪状态。 9 | - 接口注入 10 | 需要实现被注入对象对应的接口,这个接口声明一个 injectXXX 方法(方法名随意),该方法的参数,就是所依赖对象的类型。这种方式由于较繁琐且侵入性强,目前不太提倡使用了。 11 | 12 | 综上所述,构造方法注入和setter方法注入因为其侵入性较弱,且易于理解和使用,所以是现在使用最多的注入方式;而接口注入因为侵入性较强,近年来已经不流行了。 13 | 14 | ## Spring IoC 容器 15 | 上面说了几种 IoC Service Provider 实现方式,那 Spring 中是如何做的呢? 16 | 17 | Spring IoC 容器是一个 IoC Service Provider,但是,这只是它被冠以 IoC 之名的部分原因,我们不能忽略的是“容器”。Spring 的 IoC 容器是一个提供 IoC 支持的轻量级容器,除了基本的 IoC 支持,它作为轻量级容器还提供了 IoC 之外的支持。如在 Spring 的 IoC 容器之上,Spring 还提供了相应的 AOP 框架支持、企业级服务集成等服务。 18 | 19 | Spring提供了两种容器类型: BeanFactory 和 ApplicationContext。 20 | 21 | ### BeanFactory 22 | 基础类型 IoC 容器,提供完整的 IoC 服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory 是比较合适的 IoC 容器选择。 23 | 24 | #### BeanFactory 的对象注册与依赖绑定方式 25 | - 直接编码 26 | BeanFactory 接口只定义如何访问容器内管理的 Bean 的方法,各个 BeanFactory 的具体实现类负责具体 Bean 的注册以及管理工作。 BeanDefinitionRegistry 接口定义抽象了 Bean 的注册逻辑。 27 | - 外部配置文件方式 28 | Spring 的 IoC 容器支持两种配置文件格式:Properties 文件格式和 XML 文件格式。 29 | - 注解方式 30 | 使用 @Autowired 以及 @Component 对相关类进行标记。 31 | 32 | > @Autowired vs @Resource 33 | > @Resource 的作用相当于 @Autowired,均可标注在字段或属性的 setter 方法上。不过仍存在下列区别: 34 | > 1. @Resource 默认是按照名称来装配注入的,只有当找不到与名称匹配的 bean 才会按照类型来装配注入; 35 | > 2. @Autowired 默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合 @Qualifier 一起使用; 36 | > 3. @Resource 注解由 J2EE 提供,而 @Autowired 是由 spring 提供,故减少系统对 spring 的依赖建议使用 @Resource 的方式; 37 | 38 | 这里总结下注解声明和注入 Bean 的方式: 39 | - 声明 Bean 的注解: 40 | - @Component 41 | 组件,没有明确角色 42 | - @Controller 43 | 在展现层(MVC -> Spring MVC)使用 44 | - @Service 45 | 在业务逻辑层(service层)使用 46 | - @Repository 47 | 在数据访问层(dao层)使用 48 | - 注入 Bean 的注解,一般情况下通用: 49 | - @Autowired 50 | Spring 提供的注解 51 | - @Inject 52 | JSR-330 提供的注解 53 | - @Resource 54 | JSR-250 提供的注解 55 | 56 | #### 57 | 有 id, name, class 等属性。针对构造方法注入,使用 ,针对 setting 方法注入,使用 。 58 | 59 | 除了可以通过配置明确指定bean之间的依赖关系,Spring 还提供了根据 bean 定义的某些特点将相互依赖的某些 bean 直接自动绑定的功能。通过 的 autowire 属性,可以指定当前 bean 定义采用某种类型的自动绑定模式。这样,你就无需手工明确指定该 bean 定义相关的依赖关系,从而也可以免去一些手工输入的工作量. 60 | Spring提供了5种自动绑定模式,即 no、byName、byType、constructor 和 autodetect。 61 | 62 | #### bean scope 63 | scope 即容器中的对象所应该处的限定场景或者说该对象的存活时间。Spring 容器最初提供了两种 bean 的 scope 类型: singleton(单例) 和prototype(原型),但发布 2.0 之后,又引入了另外三种 scope 类型,即 request、session 和 global session 类型。不过这三种类型有所限制,只能在 Web 应用中使用。 64 | 65 | - singleton scope 66 | 一个容器中只存在一个共享实例,所有对该类型 bean 的依赖都引用这一单一实例。从容器启动,到它第一次被请求而实例化开始,只要容器不销毁或者退出,该类型 bean 的单一实例就会一直存活。 67 | 68 | - prototype scope 69 | 每次注入或通过 ContextApplication 获取时,都会创建一个新的 bean 实例。 70 | 71 | 默认情况下,Spring 中所有 bean 都是单例形式创建的,即不管给定的 bean 被注入到其他 bean 多少次,每次注入的都是同一个实例。如果选择其他作用域,要使用 `@Scope` 注解声明。 72 | 73 | 在 Web 应用中,如果能实例化在 session 和 request 范围内共享的 bean,是非常有价值的。典型的电子商务应用中,若一个 bean 代表用户的购物车,如果该 bean 是单例的话,那将导致所有用户都向一个购物车中添加商品;另外一方面,如果购物车是原型作用域的,那么在应用的一个地方往购物车添加商品,在应用的另外一个地方可能就不可用了。就此场景而言,会话作用域是最合适的。 74 | 75 | ### ApplicationContext 76 | ApplicationContext 在 BeanFactory 的基础上构建,是相对比较高级的容器实现,除了拥有 BeanFactory 的所有支持,ApplicationContext 还提供了其他高级特性,比如事件发布、国际化信息支持等。ApplicationContext 所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。所以,相对于 BeanFactory 来说,ApplicationContext 要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之 BeanFactory 也会长一些。在那些系统资源充足,并且要求更多功能的场景中,ApplicationContext 类型的容器是比较合适的选择。 77 | -------------------------------------------------------------------------------- /spring/2_wring_bean.md: -------------------------------------------------------------------------------- 1 | # 装配 Bean 2 | 3 | Spring 提供了三种主要的装配 Bean 的机制: 4 | - 在 XML 中进行显式配置; 5 | - 在 Java 中进行显式配置; 6 | - 隐式的 bean 发现机制和自动装配。 7 | 8 | 虽然 Spring 提供了多种方案来配置 bean,不过还是推荐尽可能的使用自动装配的机制。当必须使用显式配置时,优先使用 JavaConfig 的方式进行配置,最后当想使用便利的 XML 命名空间,并且在 JavaConfig 中没有同样的实例时,才应该使用 XML。 9 | 10 | ## 自动装配 bean 11 | 12 | Spring 从两个角度来实现自动化装配: 13 | - 组件扫描(component scan): Spring 自动发现 ApplicationContext 中创建的 bean。 14 | - 自动装配(autowiring):Spring 自动满足 bean 之间的依赖。 15 | 16 | Spring 使用 `@Component` 注解申明类为组件类,并知知 Spring 要为这个类创建 bean。尽管我们没有明确为目标类设置 ID,但 Spring 会根据类名为其指定一个 ID,规则是将类名的每一个大写字母改为小写字母。如果想为类设置不同的 ID,可将 ID 传递给 `@Component` 注解,如 `@Component("testClass")`。另外 Java 还提供了一种 `@Named` 的注解,两者有细微的差异,但大多数场景,两者可互相替换。 17 | 18 | Spring 使用 `@ComponentScan` 来进行组件扫描。默认情况下,`@ComponentScan` 以配置类所在的包作为基础包来扫描组件。若希望扫描不同的包,可指定 `@ComponentScan` 中的 value 属性,如 `@ComponentScan("testClass")`。如果想更加清楚的表明设置的是基础包,可设置 `basePackages` 属性:`@ComponentScan(basePackages={AClass.class, BClass.class})`。 19 | 20 | Spring 使用 `@Autowired` 注解来实现组件的自动装配。如果有且只有一个 bean 匹配依赖需求的话,那么这个 bean 会被装配进来;如果没有匹配的 bean,那么 Spring 会抛出一个异常,为避免抛出异常,可将 `@Autowired` 的 `required` 属性设置为 false,不过此时需进行 null 检查,防止使用该未装配的状态而导致 NullPointerException;如果有多个 bean 满足依赖关系,则需明确指定使用哪个 bean 进行自动装配:可将可选的某个 bean 设为首选(设置为 `@Primary`)的 bean,或使用限定符(`@Qualifier`)来将可选 bean 的范围缩小到只有一个 bean。若多个有歧义的 bean 都设置为了 `@Primary`,则需使用限定符这种方式了。 21 | 22 | ### 通过 Java 代码装配 bean 23 | 尽管多数场景下通过组件扫描和自动装配能实现 Spring 的自动化装配,但部分场景自动化配置的方案是行不通的,需要明确配置 Spring。比如想将第三方库中的组件装配到你的应用中,此时没有办法在它的类上添加 `@Component` 和 `@Autowired` 注解,此时必须采用显式装配的方式。 24 | 25 | `@ComponentScan` 和显式配置能同时使用,但这里关注显式配置,因此下面说下显式配置移除 `@ComponentScan` 后的组件扫描方法。 26 | -------------------------------------------------------------------------------- /spring/3_aop.md: -------------------------------------------------------------------------------- 1 | # AOP 2 | 3 | 待补充。 4 | -------------------------------------------------------------------------------- /spring/4_springmvc.md: -------------------------------------------------------------------------------- 1 | # Spring MVC 2 | 3 | ## Spring MVC 处理请求的过程 4 | 如下图是 Spring MVC 请求经历的所有站点: 5 | ![Spring MVC 请求过程](img/springmvc_requrest.png) 6 | 7 | - 同大多数 Java Web 框架一样,Spring MVC 的请求会先通过一个前端控制器 Servlet,在 Spring 中即 `DispatcherServlet`。 8 | - `DispatcherServlet` 的任务是将请求发送给 Spring MVC 控制器(controller)。一般应用程序会有多个 controller,所以 `DispatcherServlet` 会查询一个或多个处理器映射(handler mapper)来确定合适的控制器。处理映射器会根据请求所携带的 URL 信息来进行决策。 9 | - 一旦确定合适的控制器后, `DispatcherServlet` 会将请求发送给选中的控制器,控制器会读取用户提交的信息并开始处理数据(一般而言,设计良好的控制器基本不处理工作,而是将业务逻辑委托给服务对象处理)。 10 | - 控制器在完成逻辑处理后,通常会返回一些信息,这些信息被称为模型(model),控制器将模型数据打包,并标示出用于渲染输出的视图名。接下来连同模型和视图名发送回 `DispatcherServlet`。 11 | - `DispatcherServlet` 使用视图解析器(view resolver)将逻辑视图名匹配为一个特定的视图实现。 12 | - `DispatcherServlet` 将模型数据交给视图渲染结果。 13 | - 视图将模型结果通过响应传递给客户端。 14 | 15 | 在正式使用 Spring MVC 前,先说下 Spring MVC 的搭建过程。 16 | 17 | ## Spring MVC 的搭建过程 18 | ### 配置 `DispatcherServlet` 19 | 按照传统方式,像 `DispatcherServlet` 这样的 servelt 会配置在 web.xml 中,但借助于 Servlet 3 规范和 Spring 3.1 的功能增强,我们可以在代码中通继承 `AbstractAnnotationConfigDispatcherServletInitializer` 来实现 `DispatcherServlet` 的配置。 20 | 21 | [AbstractAnnotationConfigDispatcherServletInitializer](https://docs.spring.io/spring/docs/5.1.6.RELEASE/javadoc-api/org/springframework/web/servlet/support/AbstractAnnotationConfigDispatcherServletInitializer.html) 提供了创建 root application (代理给`ContextLoaderListener.ContextLoaderListener` 创建 `DispatcherServlet` 的父上下文)和 servlet application 的方法,并通过 `getRootConfigClasses()` 指定 root 配置类和 `getServletConfigClasses` 指定 `DispatcherServlet` 配置类: 22 | 23 | ``` 24 | 25 | public class SpittrWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 26 | 27 | ... 28 | @Override 29 | protected Class[] getRootConfigClasses() { 30 | return new Class[]{RootConfig.class}; 31 | } 32 | 33 | 34 | @Override 35 | protected Class[] getServletConfigClasses() { 36 | return new Class[]{WebConfig.class}; 37 | } 38 | 39 | ... 40 | } 41 | ``` 42 | 43 | ### 启用 Spring MVC 44 | 通过 `@EnableWebMvc` 即可启动 Spring MVC,但还有不少问题要解决: 45 | - 用户可配置视图解析器,否则 Spring 默认使用 `BeanNameViewResolver` 来查找 ID 与视图名称匹配的 bean,并且查找找 bean 要实现 view 接口。 46 | - 由于未启动组件扫描,Spring 只能找到显式声明在配置类中的控制器。这里可以通过 `@ComponentScan` 开启组件扫描。 47 | - 用户还可以配置静态资源的处理。 48 | 49 | 50 | ## 编写控制器 51 | 52 | 通过 `@Controller` 声明控制器,使用 `@RequestMapping` 来匹配请求。 53 | 54 | ## 处理请求参数 55 | Spring MVC 允许多种方式将客户端的数据传送到控制器的处理器中: 56 | - 查询参数 57 | 查询参数通过 `@RequestParam` 获取。 58 | - 路径参数 59 | 表单参数通过 `@PathVariable` 获取 `@RequestMapping` 中的占位符(使用`{}`)。 60 | - 表单参数 61 | 通过指定对象保存。 62 | 63 | -------------------------------------------------------------------------------- /spring/img/springmvc_requrest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/spring/img/springmvc_requrest.png -------------------------------------------------------------------------------- /spring/springboot/01_intro.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | ## 代码结构 4 | 5 | - 将 Java 类文件放在包中。 6 | - 将主程序入口放 root 包下,同其他包平级。 7 | - 优先使用注解配置 8 | - 使用将 `@SpringBootApplication` 或 `@EnableAutoConfiguration` 中一个来选择自动配置。 9 | 10 | ## 使用 `@SpringBootApplication` 注解 11 | `@SpringBootApplication` 提供如下功能: 12 | - `@EnableAutoConfiguration` 13 | - `@ComponentScan` 14 | - `@Configuration` 15 | 16 | 上述三个注解并不是一定需要的,可以选择其中一个或两个来代替 `@SpringBootApplication` 。 17 | -------------------------------------------------------------------------------- /spring/springboot/README.md: -------------------------------------------------------------------------------- 1 | # Spring Boot HandBook 2 | 3 | 基于 Spring Boot 2.0.5 的文档 4 | 5 | 6 | ## 参考 7 | - [Learn Spring Boot](https://www.baeldung.com/spring-boot) 8 | - [boot-documentation](https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#boot-documentation) 9 | -------------------------------------------------------------------------------- /storm/storm_tutorial.md: -------------------------------------------------------------------------------- 1 | storm单机安装及运行 2 | === 3 | 4 | Installation 5 | --- 6 | storm需要先安装以下工具: 7 | 8 | - python 9 | - zookeeper 10 | - zeromq 11 | - jzmq 12 | - storm 13 | 14 | 安装好以上工具之后,在bash中设置storm、zookeeper的环境。然后修改storm和zookeeper的配置文件。 15 | 16 | - zookeeper 17 | 18 | ``` 19 | zookeeper$ cp conf/zoo_sample.cfg conf/zoo.cfg 20 | ``` 21 | - storm 22 | 修改storm.yaml文件: 23 | 24 | ```java 25 | storm.zookeeper.servers: 26 | - "127.0.0.1" 27 | 28 | nimbus.host: "192.168.188.33" 29 | topology.debug: true 30 | ``` 31 | 32 | Run 33 | --- 34 | ### zookeeper 35 | 36 | 启动zookeeper,并查看状态 37 | 38 | ``` 39 | zookeeper$ bin/zkServer.sh start 40 | zookeeper$ bin/zkServer.sh status 41 | JMX enabled by default 42 | Using config: /home/lucky/software/zookeeper-3.4.6/bin/../conf/zoo.cfg 43 | Mode: standalone 44 | ``` 45 | 46 | ### 启动storm 47 | 启动storm的nimbus, supervisor和ui. 48 | 49 | ```java 50 | storm$ storm nimbus & 51 | storm$ storm supervisor & 52 | storm$ storm ui & 53 | ``` 54 | 55 | 在浏览器上打开`localhost:8080`可以看到UI状态。 56 | 57 | 由此storm单机安装完成。 58 | 59 | maven运行storm-starter 60 | --- 61 | 在运行之前,需要安装mvn,mvn相关见[maven](https://github.com/beitian/docs/blob/master/java/maven.md).接着操作如下: 62 | 63 | ``` 64 | $ https://github.com/apache/incubator-storm 65 | $ cd incubator-storm/examples/storm-starter 66 | $ mvn package 67 | ``` 68 | 69 | 可以见到`storm-starter/target`目录下已生成需要的jar包。接下来用storm运行生成的jar包。 70 | 71 | ```java 72 | $ cd target 73 | $ storm jar storm-starter-0.9.2-incubating-SNAPSHOT.jar storm.starter.WordCountTopology WordCount_test 74 | ``` 75 | 76 | 可以在浏览器(UI)中看到该topology。 77 | 78 | IntelliJ IDEA运行storm-starter 79 | --- 80 | 按照[using storm-starter with IDEA](https://github.com/apache/incubator-storm/tree/master/examples/storm-starter#using-storm-starter-with-intellij-idea)导入storm-start之后,还**需要导入storm的jar包**,才可以运行WordCountTopology。 81 | 82 | Reference List 83 | --- 84 | - [Command line client](https://github.com/nathanmarz/storm/wiki/Command-line-client) 85 | - [storm-start](https://github.com/apache/incubator-storm/tree/master/examples/storm-starter) 86 | -------------------------------------------------------------------------------- /tensorflow/docs/README.md: -------------------------------------------------------------------------------- 1 | # Catalog 2 | - [介绍](intro.md) 3 | -------------------------------------------------------------------------------- /tensorflow/docs/intro.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | ## 概念 4 | - 样本 5 | 一组记录的集合,其中每条记录是关于一个事件或对象的描述。 6 | - 特征 7 | 样本的特点,如样本是几条鸢尾花数据,则特征为花萼长度、花瓣长度等。 8 | - 标签 9 | 样本的分类,即尝试预测的内容。比如是山鸢尾还是变色鸢尾等。 10 | - 模型 11 | 特征与标签的关系。对于鸢尾花问题,模型定义了花萼和花瓣测量值与鸢尾花品种之间的关系。 12 | - 训练 13 | 训练是机器学习中的一个阶段,在此阶段中,模型会逐渐得到优化。 14 | 15 | ## 安装 TensorFlow 16 | 使用 Anaconda3 安装 TensorFlow,参考[这里](https://www.tensorflow.org/install/install_linux)。这里创建 Python3.6 的环境,如下: 17 | ``` 18 | // 创建名为 py3 的 python3.6.5 环境 19 | $ conda create -n py3 python=3.6.5 20 | // 安装 Jupyter、TensorFlow 21 | $ conda install -n py3 jupyter tensorflow pandas 22 | // 列举安装的包 23 | $ conda list -n py3 24 | // 激活 25 | $ source activate py3 26 | // 退出 27 | $ source deactivate 28 | ``` 29 | 这里使用 jupyter 做为学习 TensorFlow 的工具,进入 anaconda 环境后,运行 jupyter: 30 | - 生成配置文件:`$ jupyter notebook --generate-config`。 31 | - 配置: 32 | 修改配置如下: 33 | ``` 34 | c.NotebookApp.ip='*' 35 | c.NotebookApp.open_browser = False 36 | ``` 37 | 保存后退出。 38 | - 设置 jupyter 密码:`jupyter notebook password`。 39 | - 运行 jupyter: `jupyter notebook`。 40 | 41 | ## 运行 Demo 42 | 43 | 44 | ## 分析 Demo 45 | ### TensorFlow 编程堆栈 46 | 在分析 Demo 前,先看下 TensorFlow 的编程堆栈: 47 | 48 | ![TensorFlow 编程环境](../img/tensorflow_programming_environment.png) 49 | 50 | ### 过程分析 51 | 52 | 一般而言,运行 TensorFlow 主要是如下几个步骤: 53 | - 导入和解析数据集。 54 | - 创建特征列以描述数据。 55 | - 选择模型类型。 56 | - 训练模型。 57 | - 评估模型的效果。 58 | - 让经过训练的模型进行预测。 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /tensorflow/docs/read_data.md: -------------------------------------------------------------------------------- 1 | ## 读取数据 2 | 3 | 各种类型: 4 | https://www.tensorflow.org/api_guides/python/io_ops 5 | 6 | FRecords: DataLossError: 7 | https://github.com/tensorflow/tensorflow/issues/6164 8 | 9 | TensorFlow数据读取方法: 10 | http://honggang.io/2016/08/19/tensorflow-data-reading/ 11 | -------------------------------------------------------------------------------- /tensorflow/docs/tfrecord简介.md: -------------------------------------------------------------------------------- 1 | # tfrecord 简介 2 | tfrecord 是TensoFlow 官方推荐的一种较为高效的数据读取方式。生成 tfrecord 格式的文件一般过程是先读取原生数据,然后转换为 tfrecord 格式,再存储到硬盘上。使用 tfrecord 文件时,把数据从相应的 tfrecord 文件中解码读取出来即可。 3 | 4 | ## tfrecord 格式简介 5 | 参考 [example.proto](https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/core/example/example.proto) 和 [feature.proto](https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/core/example/feature.proto),代码如下: 6 | ``` 7 | // example.proto 8 | message Example { 9 | Features features = 1; 10 | }; 11 | 12 | message SequenceExample { 13 | Features context = 1; 14 | FeatureLists feature_lists = 2; 15 | }; 16 | 17 | // feature.proto 18 | message Feature { 19 | oneof kind { 20 | BytesList bytes_list = 1; 21 | FloatList float_list = 2; 22 | Int64List int64_list = 3; 23 | } 24 | }; 25 | 26 | message Features { 27 | map feature = 1; 28 | }; 29 | 30 | message FeatureList { 31 | repeated Feature feature = 1; 32 | }; 33 | 34 | message FeatureLists { 35 | map feature_list = 1; 36 | }; 37 | ``` 38 | 从注释中可以看出:Example 是 TensorFlow 中用于存储训练和预测数据的数据格式。Example 包含一个属性名称到属性值的键值对字典。其中属性名称是字段串,属性值可以为字符串(BytesList),实数列表(FloatList)和整数列表(Int64List)。如一个电影推荐应用中的一个 Example 结构如下: 39 | ``` 40 | features { 41 | feature { 42 | key: "age" 43 | value { float_list { 44 | value: 29.0 45 | }} 46 | } 47 | feature { 48 | key: "movie" 49 | value { bytes_list { 50 | value: "The Shawshank Redemption" 51 | value: "Fight Club" 52 | }} 53 | } 54 | feature { 55 | key: "movie_ratings" 56 | value { int64_list { 57 | value: 4 58 | }} 59 | } 60 | } 61 | ``` 62 | SequenceExample 是表示一个或多个序列和 context 的 Example,即属性键是一个序列,这里主要分析 Example。SequenceExample 类似,不再分析。 63 | 64 | ## 生成 tfrecord 文件 65 | 66 | 当前目录下创建目录 `tfrecords`,进入 Python,招行如下命令: 67 | ``` 68 | import tensorflow as tf 69 | import numpy as np 70 | 71 | tfrecords_filename = 'tfrecords/train.tfrecord' 72 | with tf.python_io.TFRecordWriter(tfrecords_filename) as writer: 73 | for i in range(10): 74 | img = np.random.randint(0, 255, size=(10, 10)).tostring() 75 | feature = { 76 | 'lable': tf.train.Feature(int32_list = tf.train.Int64List(value=[i])), 77 | 'img': tf.train.Feature(bytes_list = tf.train.BytesList(value=[img])) 78 | } 79 | example = tf.train.Example(features=tf.train.Features(feature=feature)) 80 | writer.write(example.SerializeToString()) 81 | ``` 82 | 83 | 代码很简单,主要是构成 Example 这块。 84 | ADD:官网关于生成 tfrecord 文件的[代码例子](https://github.com/tensorflow/tensorflow/blob/r1.3/tensorflow/examples/how_tos/reading_data/convert_to_records.py)。 85 | 86 | ## 读取 tfrecord 数据 87 | 如下: 88 | ``` 89 | def _parse_function(example_proto): 90 | features = {"image": tf.FixedLenFeature((), tf.string, default_value=""), 91 | "label": tf.FixedLenFeature((), tf.int64, default_value=0)} 92 | parsed_features = tf.parse_single_example(example_proto, features) 93 | return parsed_features["image"], parsed_features["label"] 94 | 95 | filenames = ["tfrecords/train.tfrecord"] 96 | dataset = tf.data.TFRecordDataset(filenames) 97 | dataset = dataset.map(_parse_function) 98 | ``` 99 | 100 | 参考[parse_single_example](https://www.tensorflow.org/api_docs/python/tf/parse_single_example),其原型如下: 101 | ``` 102 | parse_single_example( 103 | serialized, 104 | features, 105 | name=None, 106 | example_names=None 107 | ) 108 | ``` 109 | 110 | serialized 为一个标量(scalar)的字符串 Tensor,即一个 Example。该类型可从 `tf.TFRecordReader` 的 `read` 方法得来;或遍历`tf.data.Dataset` 得到。 111 | 112 | 113 | 114 | 这里有个问题,使用 tfrecord 和直接从硬盘读取原生数据相比,到底有什么优势呢? 115 | -------------------------------------------------------------------------------- /tensorflow/img/tensorflow_programming_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/tensorflow/img/tensorflow_programming_environment.png -------------------------------------------------------------------------------- /yarn/imgs/nmAppStatus.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mattshma/bigdata/1f27d118ef5a9f4169037d4ed767c4007a1b3a74/yarn/imgs/nmAppStatus.jpg -------------------------------------------------------------------------------- /yarn/nodemanager_app_status.md: -------------------------------------------------------------------------------- 1 | ## Nodemanager中Application和container状态分析 2 | 3 | 参考[StateMachineFactory](https://github.com/apache/hadoop/blob/branch-2.6.0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/application/ApplicationImpl.java#L130),Nodemanager中Application有如下状态: 4 | 5 | ![nm_application_status](imgs/nmAppStatus.jpg) 6 | 7 | 8 | ## 参考 9 | - [ApplicationImpl.java](https://github.com/apache/hadoop/blob/branch-2.6.0/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/application/ApplicationImpl.java) 10 | -------------------------------------------------------------------------------- /yarn/scheduler.md: -------------------------------------------------------------------------------- 1 | MRv1 Scheduler 2 | === 3 | 4 | 这里介绍下MRv1资源调度器的一些情况。原始MRv1的资源调度器是FIFO,其只能等前面所以Job执行完才能执行后面的Job。目前有两种可以选择的调度器: 5 | 6 | - [Fair Scheduler](https://hadoop.apache.org/docs/r1.2.1/fair_scheduler.html) 7 | - [Capacity Scheduler](https://hadoop.apache.org/docs/r1.2.1/capacity_scheduler.html) 8 | 9 | 在 issue 中还介绍了两种新的调度器: 10 | 11 | - [Adaptive Scheduler](https://issues.apache.org/jira/browse/MAPREDUCE-1380) 12 | - [Learning Scheduler](https://issues.apache.org/jira/browse/MAPREDUCE-1439) 13 | 14 | 这里先介绍下Capacity Scheduler。 15 | 16 | Capacity Scheduler 17 | --- 18 | Capacity Scheduler 提供多个 queue,Job都提交给queue。每个 queue 占用一部分系统资源,所以提交到queue的job都有权限使用queue。 19 | 20 | ### Features 21 | - 系统管理员可以设置软限制和可选的硬限制来限制每个queue。 22 | - 每个queue都有一个严格的 ACLs 列表来控制用户是否可以访问使用。同时有safe-guard来保证用户不能查看/修改其他用户的job。每个queue都可以设置管理员权限。 23 | - 空闲资源能被分配给任何超出容量的queue。当queue中任务请求容量大于queue限制时,该queue上的任务会被指定给有剩余容量的queue上的job去执行。这能最大化的利用集群资源。 24 | - 一些限制能防止单个job,用户,queue耗尽系统资源。 25 | - 一些设置可以job运行时配置,而且管理员和用户可以在终端中查看queue资源的分配情况。 26 | - 支持资源密集型job。可以指定超出默认设置更多的资源用来满足不同资源要求的job。目前只支持内存密集型job。 27 | - queue可支持不同优先级的job(默认不支持),在一个queue中,优先级高的job比优先级低的job更先获得资源。然后,一旦job运行起来,即使后来的job优先级再高其也不会先占其资源。 28 | 29 | Fair Scheduler 30 | --- 31 | 32 | Fair Scheduler是一种随着时间推移,所有job仍能获取同等共享资源的调度方法。当集群中仅有一个job运行时,这个job会占用集群所有资源;当有新job提交时,部分任务槽(task slot)会被腾出来分配给新的job,以使每个job都能获取大概相等的cpu时间片。Fair Scheduler 将job放入 pool 中,每个pool拥有相同的系统资源。默认情况下,每个用户有各自独立的pool。可以按照用户的unix级或job配置属性来设置job的pool。在每个pool内部,可以使用公平共享或先进先出(FIFO)来调度job。 33 | 34 | ### Features 35 | 36 | - 支持job优先级。优先级越高的job,获取的资源越多。 37 | - 每个pool可以配置最小配额的共享资源。即pool中的每个job至少会有最小配额资源。如果每个job已占有最小配额资源,此时pool还有多余资源的话,多余资源会被其他pool分掉。而如果pool中的资源不足以满足当前job的最小配额资源,调度器支持占用其他pool中job的资源,该pool被允许关掉其他pool中的任务(task),以腾出空间给当前job用。优先抢占其他pool资源有利于生产环境的job不会被同时运行在集群上的测试或研究用的job占用过多资源。当选择kill任务(task)时,Fair Scheduler会将超额job最近刚运行的task关掉,以最小化浪费机器资源。被占用资源的job不会失败,其只会延长job完成时间,因为hadoop job容忍丢失任务(task)。 38 | - 能限制每个pool每个用户并发运行的job数。 39 | - 能限制每个pool并发运行的task数 40 | 41 | ### ACLs 42 | 43 | Fair Scheduler 能和 Queue 联合起来做acl控制,这实现这样的功能,首先开启ACLs并如[MapReduce usage guide](https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Job+Authorization)所述设置一些queue。接着给每个queue的pool设置如下属性(mapred-site.xml): 44 | 45 | ``` 46 | 47 | mapred.fairscheduler.poolnameproperty 48 | mapred.job.queue.name 49 | 50 | ``` 51 | 52 | 参考 53 | --- 54 | - [Apache Capacity Scheduler Guide](https://hadoop.apache.org/docs/r1.2.1/capacity_scheduler.html) 55 | - [Cloudera Capacity Scheduler Guide](http://archive.cloudera.com/cdh/3/hadoop/capacity_scheduler.html) 56 | - [Apache Fair Scheduler](https://hadoop.apache.org/docs/r1.2.1/fair_scheduler.html) 57 | - [Cloudera Fair Scheduler](http://archive.cloudera.com/cdh/3/hadoop/fair_scheduler.html) 58 | - [MapReduce Tutorial](https://hadoop.apache.org/docs/r1.2.1/mapred_tutorial.html#Job+Authorization) 59 | - [Hadoop Fair Scheduler Design Document](https://issues.apache.org/jira/secure/attachment/12457515/fair_scheduler_design_doc.pdf) 60 | - [How to: Job Execution Framework MapReduce V1 & V2](https://www.mapr.com/blog/how-job-execution-framework-mapreduce-v1-v2#.VUcboq2qqko) 61 | 62 | -------------------------------------------------------------------------------- /yarn/yarn_tune.md: -------------------------------------------------------------------------------- 1 | 依次对如下方面说下Yarn的调优: 2 | - ResourceManager 3 | - NodeManager 4 | - ApplicationMaster 5 | - vcore 6 | - Container 7 | 8 | 9 | Configuring YARN Settings 10 | --- 11 | 12 | - mapreduce.map.memory.mb 13 | 14 | 默认为1G,这里调整为2G。 15 | 16 | - mapreduce.reduce.memory.mb 17 | 18 | 默认为1G,调整为`mapreduce.map.memory.mb`的2倍,即4G。 19 | 20 | - mapreduce.map.java.opts.max.heap 21 | 22 | 0.8 * mapreduce.map.memory.mb 23 | 24 | - mapreduce.reduce.java.opts.max.heap 25 | 26 | 0.8 * mapreduce.reduce.java.opts.max.heap 27 | 28 | - Java Heap Size of NodeManager in Bytes 29 | 4G 30 | 31 | - Java Heap Size of ResourceManager in Bytes 32 | 8G 33 | 34 | - yarn.nodemanager.resource.memory-mb 35 | 40G --> 50G 36 | 37 | - yarn.nodemanager.resource.cpu-vcores 38 | 24 --> 20 39 | 40 | - mapreduce.task.io.sort.mb 41 | 256M --> 1GB 42 | 43 | - mapreduce.task.io.sort.factor 44 | 64 --> 100 45 | 46 | - mapreduce.reduce.shuffle.parallelcopies 47 | 10 --> 50 48 | 49 | - mapreduce.job.ubertask.enable 50 | true 51 | 52 | - mapreduce.job.ubertask.maxbytes 53 | 无 --> 64M 54 | 55 | HDFS 56 | --- 57 | 58 | - Java Heap Size of Namenode in Bytes 59 | 13565MB --> 8gb 60 | 61 | - Java Heap Size of Secondary namenode in Bytes 62 | 13565MB --> 8gb 63 | 64 | 65 | 66 | 67 | ### 参考 68 | - [Yarn Overview](http://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/YARN.html) 69 | - [Tuning the Cluster for MapReduce v2 (YARN)](http://www.cloudera.com/content/cloudera/en/documentation/core/latest/topics/cdh_ig_yarn_tuning.html) 70 | 71 | -------------------------------------------------------------------------------- /zookeeper/安装部署.md: -------------------------------------------------------------------------------- 1 | # ZooKeeper安装部署 2 | 3 | 本来安装是很简单的工作,但想到未来因业务需要原因,可能还会有些安装部署zookeeper的需求,所以这是还是简单记一下。 4 | 5 | ## 下载安装zooKeeper 6 | 从[官网](http://www.apache.org/dyn/closer.cgi/zookeeper/)下载zooKeeper,解压即可,如解压在`/usr/local`目录,然后修改配置文件(`/usr/loca/zookeeper/conf/zoo.cfg`)如下: 7 | ``` 8 | tickTime=2000 9 | initLimit=10 10 | syncLimit=5 11 | dataDir=/data/zookeeper/dataDir 12 | dataLogDir=/data/zookeeper/logs 13 | clientPort=2181 14 | server.1=zk-001:2888:3888 15 | server.2=zk-002:2888:3888 16 | server.3=zk-003:2888:3888 17 | ``` 18 | 19 | 然后操作如下: 20 | ``` 21 | $ mkdir -p /data/zookeeper/{dataDir,logs} 22 | $ echo 1 > /data/zookeeper/dataDir/myid 23 | ``` 24 | 25 | 不同的zookeeper进程配置不同的myid值即可。 26 | 27 | ## 安装supervisor 28 | 一般对于zookeeper这种基础服务,都会使用supervisor进行守护,通过`easy_install supervisor`安装后,修改supervisor配置文件(`/etc/supvisord.conf`)如下: 29 | ``` 30 | [unix_http_server] 31 | file=/data/supervisor/supervisor.sock ; (the path to the socket file) 32 | 33 | [supervisord] 34 | logfile=/data/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log) 35 | logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) 36 | logfile_backups=10 ; (num of main logfile rotation backups;default 10) 37 | loglevel=info ; (log level;default info; others: debug,warn,trace) 38 | pidfile=/data/supervisor/supervisord.pid ; (supervisord pidfile;default supervisord.pid) 39 | directory=/data/supervisor 40 | childlogdir=/data/supervisor 41 | nodaemon=false ; (start in foreground if true;default false) 42 | minfds=1024 ; (min. avail startup file descriptors;default 1024) 43 | minprocs=200 ; (min. avail process descriptors;default 200) 44 | 45 | [rpcinterface:supervisor] 46 | supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface 47 | 48 | [supervisorctl] 49 | serverurl=unix:///data/supervisor/supervisor.sock ; use a unix:// URL for a unix socket 50 | 51 | [program:zookeeper] 52 | command=/usr/local/zookeeper/bin/zkServer.sh start-foreground 53 | stdout_logfile=/data/zookeeper/logs/zookeeper.log 54 | stderr_logfile=/data/zookeeper/logs/zookeeper.err 55 | stopsignal=KILL 56 | ``` 57 | 58 | 启动supervisor即可。 59 | 60 | 61 | --------------------------------------------------------------------------------