印迹

Mac Git Socks 5 代理

可以指定git地址

git config --global http.https://github.com.proxy socks5://127.0.0.1:1086

速度超快

face_recognition 梳理

1. face_recognition.api.batch_face_locations(images, number_of_times_to_upsample=1, batch_size=128)

使用cnn面部检测器返回图像中二维人脸的边界框数组,如果您正在使用GPU,这可以更快的给您结果,因为GPU可以一次处理批次的图像。如果您不使用GPU,则不需要此功能。
参数:
images - 图像列表(每个作为numpy数组)
number_of_times_to_upsample - 用于对图像进行采样的次数。较高的数字找到较小的脸。
batch_size - 每个GPU处理批次中包含的图像数量。
返回:
一个可以在css(上,右,下,左)顺序中找到的人脸位置的元组列表

2.face_recognition.api.compare_faces(known_face_encodings, face_encoding_to_check, tolerance=0.6)

将候选编码的面部编码列表进行比较,以查看它们是否匹配。
参数:

known_face_encodings - 已知面部编码的列表
face_encoding_to_check - 与已知面部编码的列表进行比较的单面编码
tolerance - 面孔之间的距离要考虑多少。越小越严格, 0.6是典型的最佳性能。

返回:
一个True / False值的列表,指出哪个known_face_encodings匹配要检查的面部编码

3.face_recognition.api.face_distance(face_encodings, face_to_compare)

给出面部编码列表,将其与已知的面部编码进行比较,并为每个比较的人脸获得欧几里得距离。距离告诉你面孔是如何相似的。
参数:

face_encodings - 要比较的面部编码列表
face_to_compare - 要比较的面部编码

返回:
一个numpy ndarray,每个面的距离与“faces”数组的顺序相同

4.face_recognition.api.face_encodings(face_image, known_face_locations=None, num_jitters=1)

给定图像,返回图像中每个面部的128维面部编码。
参数:

face_image - 包含一个或多个面的图像
known_face_locations - 可选 - 如果您已经知道它们,每个面的边框。
num_jitters - 计算编码时重新采样多少次。更高更准确,但更慢(即100是100倍慢)

返回:
128个面部编码的列表(图像中的每个脸部一个)

5.face_recognition.api.face_landmarks(face_image, face_locations=None)

给定图像,返回图像中每个脸部的脸部特征位置(眼睛,鼻子等)的指令

参数:
face_image - 要搜索的图像
face_locations - 可选地提供要检查的面部位置的列表。
返回:
面部特征位置(眼睛,鼻子等)的列表

6.face_recognition.api.face_locations(img, number_of_times_to_upsample=1, model='hog')

返回图像中人脸的边框数组
参数:

img - 一个图像(作为一个numpy数组)
number_of_times_to_upsample - 用于对图像进行上采样的次数多少次。较高的数字找到较小的脸。
model - 要使用的面部检测模型。“hog”在CPU上不太准确,但速度更快。“cnn”是一个更准确的深入学习模式,GPU / CUDA加速(如果可用)。默认为“hog”。

返回:
一个可以在css(上,右,下,左)顺序中找到的表面位置的元组列表

face_recognition.api.load_image_file(file, mode='RGB')
将图像文件(.jpg,.png等)加载到numpy数组中

参数:
file - 要加载的图像文件名或文件对象
mode - 将图像转换为格式。只支持“RGB”(8位RGB,3声道)和“L”(黑白)。
返回:
图像内容为numpy数组

aliyun maven国内镜像

settings.xml

下载速度不错,点击下面链接试试。

http://maven.aliyun.com

<?xml version="1.0" encoding="UTF-8"?>


<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" 
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">
  <!-- localRepository
   | The path to the local repository maven will use to store artifacts.
   |
   | Default: ~/.m2/repository -->
  <localRepository>e:\\data\\.m2</localRepository>
 

  <pluginGroups>

  </pluginGroups>


  <proxies>

  </proxies>


  <servers>
    
  </servers>

  <mirrors>
 
  </mirrors>
  
  <profiles>
    <profile>
        <id>aliyun_nexus</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <repositories>
        <repository>
            <id>public</id>
            <name>public</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <releases><enabled>true</enabled><updatePolicy>always</updatePolicy></releases> 
             <snapshots><enabled>true</enabled><updatePolicy>always</updatePolicy></snapshots> 
        </repository>

        <repository>
            <id>central</id>
            <name>central</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        
        <repository>
            <id>apache-snapshots</id>
            <name>apache-snapshots</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/apache-snapshots/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        
                <repository>
            <id>central-m1</id>
            <name>central-m1</name>
            <url>http://maven.aliyun.com/nexus/content/shadows/central-m1/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        <repository>
            <id>codehaus-snapshots</id>
            <name>codehaus-snapshots</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/codehaus-snapshots/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        <repository>
            <id>releases</id>
            <name>releases</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/releases/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        
        <repository>
            <id>snapshots</id>
            <name>snapshots</name>
            <url>http://maven.aliyun.com/nexus/content/repositories/snapshots/</url>
            <snapshots>
                <updatePolicy>interval:30</updatePolicy>
            </snapshots>
        </repository>
        </repositories>
    </profile>
  </profiles>
  
  <activeProfiles>
      <activeProfile>aliyun_nexus</activeProfile>
  </activeProfiles>

</settings>

大数据

1. 是个什么东西?

  1. 核心有点?
  2. 出现的问题?
  3. 优化
  4. 单独优化过?那些点

Hadoop(HDFS)

Hadoop是一个根据google三大论文实现的一套海量数据存储、计算、查询的开源大数据框架。它包含三个基础组建 HDFS、Mapreduce、Hbase

为什么HDFS的blocksize是128M?

机架位置优化
磁盘的块大小为512byte,HDFS的块大小为128Mb,主要原因是为了减少磁盘的寻道时间。一次寻道大约需要10ms,目前市面上的千兆网卡速度为100Mb/s,寻道时间应该只占传输时间的1%,我们需要设置一块的大小为100M,因此设置块的大小为128M。

HDFS不适合的场景

1)低延迟的访问 HDFS在高吞吐量的数据传输上面做了很多优化,而这是以牺牲低延迟为代价的。  
2)太多小文件  因为NameNode是在内存中保存文件的元数据的,因此能够存储的文件个数受内存大小的限制。每一个文件、目录和块都占用大约150byte,因此假设有100W个文件,每一个文件占一个块,那就需要大约300M的内存。

partition

我们对于错综复杂的数据归类。比如在动物园里有牛羊鸡鸭鹅,他们都是混在一起的,但是到了晚上他们就各自牛回牛棚,羊回羊圈,鸡回鸡窝。partition的作用就是把这些数据归类。只不过在写程序的时候,mapreduce使用哈希HashPartitioner帮我们归类了。这个我们也可以自定义。

HDFS优化项

1. dfs.block.size 块越大,元数据越少,但是影响分片时间
2. mapred.local.dir 多盘提高IO
3. yarn的容器最大内存、最小内存 对应java的最大内存最小内存。
4. nodemanager 所管理的每个节点的最大内存(留出10%~20%的余量给系统和其他)
5. CPU资源,nodemanager管理的cpu量(流出20%给系统) 虚拟cpu数量(系统一共10个cpu 核数,你可以把这个cpu个数当成20个用。这20个cpu就是虚拟出来的)

Hbase

rowkey设计
越短越好

(1)数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响HFile的存储效率;
(2)MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。因此Rowkey的字节长度越短越好。
(3)目前操作系统是都是64位系统,内存8字节对齐。控制在16个字节,8字节的整数倍利用操作系统的最佳特性。

rowkey离散

如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。

hbase 获取数据的方式:

(1) 通过单个Rowkey访问,即按照某个Rowkey键值进行get操作,这样获取唯一一条记录;
(2) 通过Rowkey的range进行scan,即通过设置startRowKey和endRowKey,在这个范围内进行扫描。这样可以按指定的条件获取一批记录;
(3) 全表扫描,即直接扫描整张表中所有行记录。

多条件查询

(1)scan可以通过setCaching与setBatch方法提高速度(以空间换时间);
(2)scan可以通过setStartRow与setEndRow来限定范围。范围越小,性能越高。
通过巧妙的RowKey设计使我们批量获取记录集合中的元素挨在一起(应该在同一个Region下),可以在遍历结果时获得很好的性能。
(3)scan可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础。
在满足长度、三列、唯一原则后,我们需要考虑如何通过巧妙设计RowKey以利用scan方法的范围功能,使得获取一批记录的查询速度能提高。下例就描述如何将多个列组合成一个RowKey,使用scan的range来达到较快查询速度。

hbase内部机制

在HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的。HBase 接到命令后存下变化信息,或者写入失败抛出异常。默认情况下,执行写入时会写到两个地方:预写式日志(write-ahead log,也称HLog)和MemStore(见图2-1)。HBase 的默认方式是把写入动作记录在这两个地方,以保证数据持久化。只有当这两个地方的变化信息都写入并确认后,才认为写动作完成。
MemStore 是内存里的写入缓冲区,HBase 中数据在永久写入硬盘之前在这里累积。当MemStore 填满后,其中的数据会刷写到硬盘,生成一个HFile。HFile 是HBase 使用的底层存储格式。HFile 对应于列族,一个列族可以有多个HFile,但一个HFile 不能存储多个列族的数据。在集群的每个节点上,每个列族有一个MemStore。
大型分布式系统中硬件故障很常见,HBase 也不例外。设想一下,如果MemStore还没有刷写,服务器就崩溃了,内存中没有写入硬盘的数据就会丢失。HBase 的应对办法是在写动作完成之前先写入WAL。HBase 集群中每台服务器维护一个WAL 来记录发生的变化。WAL 是底层文件系统上的一个文件。直到WAL 新记录成功写入后,写动作才被认为成功完成。这可以保证HBase 和支撑它的文件系统满足持久性。大多数情况下,HBase 使用Hadoop 分布式文件系统(HDFS)来作为底层文件系统。
如果HBase 服务器宕机,没有从MemStore 里刷写到HFile 的数据将可以通过回放WAL 来恢复。你不需要手工执行。Hbase 的内部机制中有恢复流程部分来处理。每台HBase 服务器有一个WAL,这台服务器上的所有表(和它们的列族)共享这个WAL。
你可能想到,写入时跳过WAL 应该会提升写性能。但我们不建议禁用WAL,除非你愿意在出问题时丢失数据。如果你想测试一下,如下代码可以禁用WAL:
注意:不写入WAL 会在RegionServer 故障时增加丢失数据的风险。关闭WAL,出现故障时HBase 可能无法恢复数据,没有刷写到硬盘的所有写入数据都会丢失。

Hive

Hive和Hbase有各自不同的特征:hive是高延迟、结构化和面向分析的,hbase是低延迟、非结构化和面向编程的。Hive数据仓库在hadoop上是高延迟的。Hive集成Hbase就是为了使用hbase的一些特性

Spark

Spark 是一个基于MapReduce模式的一个分布式并行模型计算框架,他的存储是基于内存的。

集群

Spark 集群的核心是专注于集中调度服务器上的资源进行分布式作协计算(ClusterMaster),Spark 的集群模式分为三种一种是Standalone 、Yarn、Mesos模式, Spark的资源管理一般分为Master-Worker模式。

Application

就是Spark程序入口,他指定DAG的运行流程

SparkContext

他是Spark的最核心的部分,负责用户逻辑的处理API的调用,所有交互的接口处,包括想Cluster交互申请资源等。

Driver

每个Spark Job在运行的时候都会启动一个Driver和若干Executor, Driver 将Job转化为若干Task,再将Task 提交到各个Executor上运行,
1517985514301_3

Executor

Executor是运行具体Task的地方,我认为Task的下面的小任务可以认为是一个Stage。

RDD

Rdd是Resilient Distributed Dataset 的缩写,意思是弹性分布式数据集,他是一个抽象话的概念,我们可以简单理解成程序获取了一个文件的句柄,不同文件有read/write/seek等操作,而RDD也同样有自己的操作API,他的API分为三种

  1. 创建(read) 加载数据 比如从HDFS,HBASE等其他数据源。
  2. **Transformation(转换) ** 对已有的RDD做转换操作,从而产生新的RDD,Transformation操作有懒惰机制是不会立刻运行的,只有遇到Action的时候才会进行计算。 如Map、Filter等做操
  3. Action 就是运行时调用,产生计算结果。如save操作等。 ##Partition
    Partition是RDD在物理上的分区,partition 分布在各个节点上,spark就是利用多partition实现分布式并行计算的。
    ##Dependency
    对RDD进行Transform和Action操作就会产生RDD之间的依赖,这个依赖关系可以想象成一条链条,这个链条就是DAG(有向无环图)
    这里的依赖关系分为两种:宽依赖(wide dependency)和窄依赖(norrow dependency)
    窄依赖:窄依赖是parent 的每个partition 和 children partition 是一一对应的依赖关系。
    宽依赖: 宽依赖是parent的每个分区都可能被children的多个partition所依赖,可以理解为一对多依赖关系,在这个过程中一般会有记录的互相重组,所以这个过程也叫shuffle Dependency(shuffle依赖) 。

Job

一个正常的spark任务就是一个Job,一个Job包含N个Transformation和最少1个Action。

Shuffle

Spark的架构核心和hadoop 的mapreduce是一样,所以先说下mapreduce的shuffle,通常我们把map->reduce 的中间这个过程叫做shuffle我,shuffle就是数据打诨重组的过程。再看看spark,数据打诨重组的过程只发生在宽依赖中,所以宽依赖也叫Shuffle Dependency。

Stage

Spark 里边一个Job 他会由若干个任务组成的有向五环图,Spark 以shuffle为边界,将不同的任务分配到一个stage中去。也就是从头开始只要遇到一个宽依赖就分为一个stage。一直到结束。当然stage的运行也是前后依赖的关系。这样分配的意义在于再依赖是可以通过串行计算去完成的,他会放在一个Task组里边去执行,而这些Task组也会分配到同一个Executor中去,减少网络消耗,提高运算效率。

Task

spark 的Stage 里边有很多任务,也就是Task ,这些Task会放入到一个Taskset里边去,再将TaskSet作用到每个Partition上去执行。Task就是一系列的执行动作。

Persist&Cache

Persist是讲数据加载到内存或者磁盘上,他是可以指定参数加载,而Cache就是只是将数据加载到内存中,以MEMORY_ONLY的方式进行缓存,其实cache函数就是调动persist(MEMORY_ONLY)进行缓存的
Persist 有两种触发方式,一种是执行Action的时候,另一个是在直接执行persist或者cache的时候。

Checkpoint

为什么有CheckPoint 机制,是因为spark 是内存计算模型,内存是有限的,数据是无限的,在一串任务中,如果内存不够了,那么spark就会清理掉老的RDD数据,比如: 如果你的Job任务有100个Stage,第100个stag需要依赖第2个,那么中间从第3个到99个计算中完全可能把第二个Rdd的数据清理掉,到第100Stage进行计算的时候,就需要在计算一次第二个Stage的结果。为了避免这种情况Spark,引入了checkpoint机制,就是spark需要依赖一个stage数据时候他会先check缓存-> 如果没有 -> check checkpoint ->如果没有->重新计算。这是整个命中过程。

SparkStreaming

优化

  • join操作是否可以使用map广播的方式替代。
  • 使用reduceByKey/aggregateByKey来代替groupByKey,因为前者可以进行combiner操作,减少网络IO;
  • 使用foreachPartition代替foreach操作
  • 使用foreachPartition代替foreach操作
  • 使用Repartition操作可以有效增加任务的处理并行度

参数的优化

  • 根据资源情况,可以添加Executor的个数来有效,参数为 spark.executor.instances
  • 调整每个Executor的使用内核数, 参数为spark.executor.cores
  • 调整每个Executor的内存, 参数为spark.executor.memory
  • shuffle write task的buffer大小, 参数为spark.shuffle.file.buffer
  • shuffle read task的buffer大小, 参数为spark.reducer.maxSizeInFlight
  • 每一个stage的task的默认并行度, 默认为200, 建议修改为1000左右, 参数 spark.default.parallelism
  • 用于RDD的持久化使用的内存比例,默认0.6, 参数 ** spark.storage.memoryFraction**
  • 用户shuffle使用的内存比例, 默认为0.2, 参数 ** spark.shuffle.memoryFraction**
  • 限制读取Kafka数据的速率,参数 spark.streaming.kafka.maxRatePerPartition

问题

  • 内存太小OOM
  • 块丢失
  • 数据丢失
  • 计算问题

Elasticsearch

概述

ElasticSearch是一个基于Lucene构建的开源,分布式,RESTful搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。支持通过HTTP使用JSON进行数据索引。

选用主要原因有:

实时性能优越;`安装、配置、维护、使用简单`;
`RESTful API` 和 `JSON格式的文档型数据`,降低开发调试的难度。 
`ES自带了中文分词`,支持中文搜索,但是,可以换用更高效精确的分词插件。 
他有自己`成熟的软件生态ELK`,
`强大的插件群`。
`分布式灵活扩展`
`文档齐全`
`社区强大`
 特点优势 
(1)Open Source(开源) 
(2)Apache Lucene(基于 Lucene) 
(3)Schema Free(模式自由) 
(4)Document Oriented(面向文档型的设计) 
(5)Real Time Data & Analytics(实时索引数据) 
(6)Distributed(分布式) 
(7)High Availability(高可靠性) 
(8)其他特性:RESTful API;JSON format;multi-tenancy;full text search;conflict management;per-operation persistence 

es的一些术语

cluster
  代表一个集群,集群中有多个节点,其中有一个为主节点,这个主节点是可以通过选举产生的,主从节点是对于集群内部来说的。es的一个概念就是去中心化,字面上理解就是无中心节点,这是对于集群外部来说的,因为从外部来看es集群,在逻辑上是个整体,你与任何一个节点的通信和与整个es集群通信是等价的。
shards
  代表索引分片,es可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,并且索引创建后不能更改。
replicas
  代表索引副本,es可以设置多个索引的副本,副本的作用一是提高系统的容错性,当个某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高es的查询效率,es会自动对搜索请求进行负载均衡。
recovery
  代表数据恢复或叫数据重新分布,es在有节点加入或退出时会根据机器的负载对索引分片进行重新分配,挂掉的节点重新启动时也会进行数据恢复。
river
  代表es的一个数据源,也是其它存储方式(如:数据库)同步数据到es的一个方法。它是以插件方式存在的一个es服务,通过读取river中的数据并把它索引到es中,官方的river有couchDB的,RabbitMQ的,Twitter的,Wikipedia的。
gateway

  代表es索引快照的存储方式,es默认是先把索引存放到内存中,当内存满了时再持久化到本地硬盘。gateway对索引快照进行存储,当这个es集群关闭再重新启动时就会从gateway中读取索引备份数据。es支持多种类型的gateway,有本地文件系统(默认),分布式文件系统,Hadoop的HDFS和amazon的s3云存储服务。

discovery.zen
  代表es的自动发现节点机制,es是一个基于p2p的系统,它先通过广播寻找存在的节点,再通过多播协议来进行节点之间的通信,同时也支持点对点的交互。
Transport
  代表es内部节点或集群与客户端的交互方式,默认内部是使用tcp协议进行交互,同时它支持http协议(json格式)、thrift、servlet、memcached、zeroMQ等的传输协议(通过插件方式集成)。
Mapping
mapping就是ES在索引的过程中讲字段推断为那种类型,也可以做一些设置,Mapping 可以分为settingmappings 两大类, settings主要设置一些index上的参数,如副本数,分片数;而mappings 主要是对文档结构进行描述。
mappings又可以分为三类:

我的话

优化方式有很多:

从系统大类上有ulimit 修改,如`句柄数`、`线程数`、`ES的JVM 内存调整`等;

进入ES内部优化包含也很多,举个例子就说mapping ,mapping是描述索引结构的一个术语,它主要分为两类:
    1. 一类呢:是settings,里边主要的配置项就是分片和副本数,当然也有其他的,如refresh time等。
    2. 第二类呢:mappings 它主要描述文档结构:
    它里边呢也有主要有三大配置:_all、_source、properites
        1. _all 主要是将文档中所有的字段全部包含进来进行索引了,在没有指定字段的情况下进行检索,它默认会检索这个字段,但是在我们业务中,往往都是对字段进行精确检索,我们需要关闭这个功能来提高索引速度、而且同时也会提高磁盘IO。"_all" : {"enabled" : false} 
        2. _source 主要是讲文档的所有字段数据保存在source document中,你可以理解为es不仅保存一份索引数据,而且还将原始数据进行保存下来。所以source字段在我们检索查看数据的时候很有用,如果这个字段{"enabled" : false} 那么检索的时候只返回ID,es就需要通过字段取索引中获取数据,效率就很低了,如果{"enabled" : true} 就会产生另外一个问题,那就是索引膨胀的速度就非常的快,我们就可以通过Compress来设置的是否压缩。
        2.1 当然,也有少数场景是可以关闭 _source 的:
        - 把 ES 作为时间序列数据库使用,只要聚合统计结果,不要源数据内容。
        - 把 ES 作为纯检索工具使用,_id 对应的内容在 HDFS 上另外存储,搜索后使用所得 _id 去 HDFS 上读取内容。


        3. propertis 就是最主要的指定文档结构了,它包括字段类型、父子关系,也就是主要的数据建模部分。这个根据业务的不同优化点也不同。比如: 他有很多数据类型,除了int string float之外还有数组类型、对象类型,如果只是geo的话还有geopoint类型、嵌套类型等。
        
    **优化篇:**
    ES作为一个快速搜索引擎最核心的功能就是,索引和检索,如何提高他的索引效率就是ES优化的核心问题:
    "index.translog.flush_threshold_ops": "100000" 
    "index.refresh_interval": "-1", 
    1. translog主要是让ES集群各个节点之间进行数据平衡,ES 做translog的这个过程比较消耗时间和资源,第一个参数是达到多少条进行translog操作,这个参数默认是5000, 可以将它调大些。 第二个参数 是集群每隔多少秒进行一次translog操作,模式120s ,这个频率太高设置大些(需要根据业务)或者直接设置为-1 我们手动做同步。
    
    2. 分片数量的选取
    测试分片数量=数据总量/单片数据总量
    需要计算单片数据总量达到多少时候可以满足要求:
    经验:单片不要超过1.88亿条,每个机器不要超过200个分片。
    
    3. 副本的选取
    es的副本机制会保障es在某一数据片失败的情况下进行数据恢复,保证数据的安全性。而es的副本机制还有一个特性就是,在高效检索的情况下做负载均衡,以提高检索效率;事实证明副本数不是越多或越少都不好,只有根据集群配置选取适中的副本数量就可以了。建议副本数为1~3个。副本优化案例:
        3.1 主片体现了索引,副片没有体现索引,是应为settings里边translog没有到达同步时间。
        3.2 在进行大规模数据导入的时候,进行讲副本数设置为0 ,因为在导入的过程中,副本也同时在复制,导致效率下降,同步完成之后将副本设置为1,他会自动复制副本。从而达到高效数据导入。
    4. 索引段segment
    es的底层是lucence,lucence 的索引保存在磁盘上的文件就是segment,segment 越多检索速度就越慢,es可以设置max_num_segments=1 也就是不让segment分裂,这样就可以保障快速检索。但是如果我们的数据量巨大,name这个segment就会特别大,检索起来也会有问题,而且大大提高索引错误率。所以这个优化需要慎重。
    5. 删除文档
    
    
    
    
    

遇到的问题

比如索引速度慢,查询速度慢。
索引速度调整索引 refresh_interval 、translog时间、副本数量等。
查询速度慢, 查询语句复杂,join过程优化。
分片复制错误等。 ulimit太小导致不能写入。

Data too large : indices.fielddata.cache.size ,在该数值达到一个百分比的时候会自动清空缓存,默认是无限制 就会产生该错误。设置为30%

Solr和ES对比

首先solr和ES都是基于lucence的开发的,有人ES的性能要优于solr我觉得其实不然,首先两者都是基于lucence、JVM ,虽然底层相同单他们各自有不用feature,不同的feature他的 test case (测试场景) 就不同,所以做benchmark 的意义就不是大。
我觉得ES能流行的原因是可能是, es 出现的时候比较晚,无论在设计上还是实现上都比较考究,新式吧,也就是比较接地气,更容易上手。加上Elastic 的生态也比较完善,扩展性更强,我们随便扩展自己的插件,说到这里es的插件生态也非常强大,几乎覆盖大数据生态相关组件,在这方面solr就逊色很多。

大面上的配置

索引分片数 index.number_of_shards: 5 
 
索引副本数  index.number_of_replicas: 1 

机架配置   node.rack_id:rack_one

内存配置  ES_MIN_MEM=27G  ES_MAX_MEM=27G 

优化配置

bootstrap.mlockall: true #这样可以elasticsearch确保使用物理内存,不使用linux swap 。

Mapping

Kafka

概述

Kafka是最初由Linkedin公司开发,是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统,它的最大的特性就是可以实时的处理大量数据以满足各种需求场景:比如基于hadoop的批处理系统、低延迟的实时系统、storm/Spark流式处理引擎,web/nginx日志、访问日志,消息服务等等,用scala语言编写,Linkedin于2010年贡献给了Apache基金会并成为顶级开源 项目。
他的结构是: 它分为 topic->broker->partion-> 副本
他的使用模式很简单就是生产者消费者模式,生产者可以有多个,而他的消费者最好和他的partition数量相同,如果大于partition个数那么多余的consumer,

Kakfa Broker Leader的选举: 抢占式做Leader,谁第一个到就是谁。同时已有一个Broker可以做leader。
Consumergroup

  • 每个消费者都所属一个分组,分组的多少是可以有多个的。
  • 每个组的消费情况使用offset来控制,
  • 无论consumer 的thread有多少,都会讲所有partition消费完。
  • Consumer的增加或者减少都会进行balence操作

Partition leader与follower
partition和副本的关系是leader和follower的关系,producer写kafka的时候先写partition leader,再由partition leader push给其他的partition follower

遇到的问题

1.一个partition只能被一个消费者消费(一个消费者可以同时消费多个partition)
2.分区数据量不均衡:
Topic上设置了四个分区,压测过程中,发现每个分区的数据量差别挺大的,极端的时候,只有一个分区有数据,其余三个分区空闲。
解决方法,在用生产者生产数据的时候,send方法需要指定key。Kafka会根据key的值,通过一定的算法,如hash,将数据平均的发送到不同的分区上。

  1. kafka的副本问题。
    副本不参与消费。
    参考:http://blog.csdn.net/ychenfeng/article/details/74980531

粘贴板

粘贴板操作是很有用的,比如你需要粘贴一段文字,不想要他的格式只想要他的文字或者格式和文字都想要,你复制一个图片信息粘贴导致本地的时候想保存为一个文件,系统是怎么实现的呢。

真相

系统的粘贴功能其实有一个规范的规范编号为:rfc2045
英文名:Multipurpose Internet Mail Extensions (MIME) Part One:Format of Internet Message Bodies
中文翻译:多用途多格式邮件扩展-信体格式说明书
链接:http://www.ietf.org/rfc/rfc2045.txt

这个规范主要描述了网络数据协议格式.格式为:

     entity-headers := [ content CRLF ]
                       [ encoding CRLF ]
                       [ id CRLF ]
                       [ description CRLF ]
                       *( MIME-extension-field CRLF )

     MIME-message-headers := entity-headers
                             fields
                             version CRLF
                             ; The ordering of the header
                             ; fields implied by this BNF
                             ; definition should be ignored.

     MIME-part-headers := entity-headers
                          [ fields ]
                          ; Any field not beginning with
                          ; "content-" can have no defined
                          ; meaning and may be ignored.
                          ; The ordering of the header
                          ; fields implied by this BNF
                          ; definition should be ignored.
#其中 Content-type: 
#image/x-java-image
#Content-type: text/plain; charset=us-ascii 
#...等格式类型

好了以上是一般操作系统粘贴使用的粘贴板协议概述。
详细可以参照rfc2045

Java中的粘贴板

java 中使用awt实现rfc2045 协议,
java.awt.datatransfer.Transferable
java.awt.datatransfer.DataFlavor
java.awt.datatransfer.Clipboard
这三个类实现RFC2045协议

具体Demo代码

package com.ghw.test;

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStreamReader;
import java.util.List;

/**
 * Created by cocky on 2017/3/1.
 */
public class TestPaste {
    public String getClipboardText(Clipboard clip) throws Exception {
        Transferable clipT = clip.getContents(null);
        if (clipT != null) {
            if (clipT.isDataFlavorSupported(DataFlavor.stringFlavor))
                return (String) clipT.getTransferData(DataFlavor.stringFlavor);

        }
        return null;
    }
    public BufferedImage getClipboardImage(Clipboard clip) throws Exception {
        Transferable clipT = clip.getContents(null);
        if (clipT != null) {
            if (clipT.isDataFlavorSupported(DataFlavor.imageFlavor))
                return (BufferedImage) clipT.getTransferData(DataFlavor.imageFlavor);
            else {
                System.out.println("Not support");
            }

        }
        return null;
    }


    public InputStreamReader getClipboardplainInputStream(Clipboard clip) throws Exception {
        Transferable clipT = clip.getContents(null);
        if (clipT != null) {
            //自动识别最好的Flavor
            if (clipT.isDataFlavorSupported(DataFlavor.getTextPlainUnicodeFlavor()))
                return (InputStreamReader)clipT.getTransferData(DataFlavor.selectBestTextFlavor(clipT.getTransferDataFlavors()));
            else {
                System.out.println("Not support");
            }

        }
        return null;
    }

    public java.util.List<File> getClipboardFile(Clipboard clip) throws Exception {
        Transferable clipT = clip.getContents(null);
        if (clipT != null) {
            //自动识别最好的Flavor
            if (clipT.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
                return (java.util.List<File>)clipT.getTransferData(DataFlavor.javaFileListFlavor);
            else {
                System.out.println("Not support");
            }

        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        TestPaste testpaste = new TestPaste();
        Clipboard systemClipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        //直接就是文本,也可以支持把html转为text
        System.out.println("===:"+testpaste.getClipboardText(systemClipboard));
        //图片
        System.out.println("===:"+testpaste.getClipboardImage(systemClipboard));

        //二进制流
        //InputStreamReader paste = testparse.getClipboardplainInputStream(systemClipboard);
        //System.out.println(IOUtils.toString(paste));
        List<File> clipboardFile = testpaste.getClipboardFile(systemClipboard);
        System.out.println(clipboardFile);

    }
}


centos 安装apache + ssl证书

免费证书申请和安装

申请证书

去阿里云平台找证书管理
然后证书购买 第二项就是免费申请证书,每个用户最多可以申请20个。
申请的同时需要你验证域名的有效性。配置CNAME 到你的域名解析,然后自动验证。
验证服务在国外你可以通过dig命令来验证你的CNAME是否生效

#国外环境,aliyun-赛门铁克 根据这个验证的。
dig sg7tskhqag0k9be2jdjapn7ej7oc04uc.cellinfor.com @8.8.8.8
#国内环境
dig sg7tskhqag0k9be2jdjapn7ej7oc04uc.cellinfor.com

如果生效他会通知

Linux 模块

yum -y  install openssl mod_ssl apache

[root@host conf.d]# pwd
/etc/httpd/conf.d
[root@host conf.d]# ll
total 24
-rw-r--r-- 1 root root  392 Jan 12 12:10 README
-rw-r--r-- 1 root root  674 Aug 11  2016 php.conf
-rw-r--r-- 1 root root 9749 Feb 13 02:30 ssl.conf
-rw-r--r-- 1 root root  299 Dec 13 04:27 welcome.conf

[root@host conf.d]# vi ssl.conf
配置你的证书就可以了
#SSLProtocol all -SSLv2
SSLProtocol TLSv1 TLSv1.1 TLSv1.2
#SSLCipherSuite DEFAULT:!EXP:!SSLv2:!DES:!IDEA:!SEED:+3DES
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4

#SSLCertificateFile /etc/pki/tls/certs/localhost.crt
SSLCertificateFile /etc/httpd/cert/public.pem

#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key
SSLCertificateKeyFile /etc/httpd/cert/214015393150976.key

#SSLCertificateChainFile /etc/pki/tls/certs/server-chain.crt
SSLCertificateChainFile /etc/httpd/cert/chain.pem

安装证书

文件说明:

  1. 证书文件214015393150976.pem,包含两段内容,请不要删除任何一段内容。

  2. 如果是证书系统创建的CSR,还包含:证书私钥文件214015393150976.key、证书公钥文件public.pem、证书链文件chain.pem。

( 1 ) 在Apache的安装目录下创建cert目录,并且将下载的全部文件拷贝到cert目录中。如果申请证书时是自己创建的CSR文件,请将对应的私钥文件放到cert目录下并且命名为214015393150976.key;

( 2 ) 打开 apache 安装目录下 conf 目录中的 httpd.conf 文件,找到以下内容并去掉“#”:

#LoadModule ssl_module modules/mod_ssl.so (如果找不到请确认是否编译过 openssl 插件)
#Include conf/extra/httpd-ssl.conf

( 3 ) 打开 apache 安装目录下 conf/extra/httpd-ssl.conf 文件 (也可能是conf.d/ssl.conf,与操作系统及安装方式有关), 在配置文件中查找以下配置语句:

# 添加 SSL 协议支持协议,去掉不安全的协议
SSLProtocol TLSv1 TLSv1.1 TLSv1.2
# 修改加密套件如下
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4
# 证书公钥配置
SSLCertificateFile cert/public.pem
# 证书私钥配置
SSLCertificateKeyFile cert/214015393150976.key
# 证书链配置,如果该属性开头有 '#'字符,请删除掉
SSLCertificateChainFile cert/chain.pem

( 4 ) 重启 Apache。

( 5 ) 通过 https 方式访问您的站点,测试站点证书的安装配置,如遇到证书不信任问题,请查看相关文档。

What is Slack?

https://slack.com/
知乎-如何评价协作工具 Slack?

依赖

https://github.com/allbegray/slack-api

Maven

Step 1. Add the JitPack repository to your build file

<repository>
    <id>jitpack.io</id>
    <url>https://jitpack.io</url>
</repository>

Step 2. Add the dependency in the form

<dependency>
    <groupId>com.github.allbegray</groupId>
    <artifactId>slack-api</artifactId>
    <version>v1.3.0.RELEASE</version>
</dependency>

代码

package com.test.slack;

import allbegray.slack.SlackClientFactory;
import allbegray.slack.SlackTextBuilder;
import allbegray.slack.rtm.Event;
import allbegray.slack.rtm.EventListener;
import allbegray.slack.rtm.SlackRealTimeMessagingClient;
import allbegray.slack.webapi.SlackWebApiClient;
import com.fasterxml.jackson.databind.JsonNode;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

/**
 * Created by cocky on 2017/3/8.
 */
public class MainTest {

    public static String exec(String cmd){
        InputStream in = null;
        StringBuffer sb= new StringBuffer();
        try {
            Process pro = Runtime.getRuntime().exec(cmd);
            pro.waitFor();
            in = pro.getInputStream();
            BufferedReader read = new BufferedReader(new InputStreamReader(in));
            String result = null;
            while ((result=read.readLine())!=null){
                sb.append(result+"\n");
            }

            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static void main(String[] args) {

        listening();
        //System.out.println(exec("ls"));


    }

    static String message = SlackTextBuilder.create()
            .text("text message")
            .newline()
            .link("https://slack.com/")
            .link("https://slack.com", "Slack")
            .newline()
            .bold("bold message")
            .italic("italic message")
            .strike("strike message")
            .newline()
            .mail("test@test.com")
            .mail("test@test.com", "TestMail")
            .newline()
            .code("code block")
            .preformatted("public class SlackWebhookClientTest() {\n\n\tpublic static void main(String args[]) {\n\n\t}\n}")
            .quote("quote message")
            .build();

    private static void listening() {
        final SlackRealTimeMessagingClient rtmClient = SlackClientFactory.createSlackRealTimeMessagingClient("xoxb-151982105191-Fnk3VsRbyigJDDyupEvSQMla");
        final SlackWebApiClient webApiClient = SlackClientFactory.createWebApiClient("xoxb-151982105191-Fnk3VsRbyigJDDyupEvSQMla");

        rtmClient.addListener(Event.MESSAGE, new EventListener() {
            public void handleMessage(JsonNode jsonNode) {
                System.out.println(jsonNode);

                System.out.println("Send=====: "+ jsonNode.get("text").asText());

                if(jsonNode.has("subtype") && "bot_message".equals(jsonNode.get("subtype").asText())) {
                    return;
                }


                try {
                    //webApiClient.postMessage("#test", exec(jsonNode.get("text").asText()));
                    webApiClient.postMessage("#test", message);
                }catch (Exception e){
                    e.printStackTrace();
                }

            }
        });

        rtmClient.connect();

        try {
            Thread.sleep(1000 * 1000);
            rtmClient.close();
            webApiClient.shutdown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

效果

image.png

Ambari安装记录

下面是ambari的安装记录,由于写的人懒所以只记录了核心部分。

1.关闭防火墙

service iptables stop
chkconfig iptables off

2.无密码登录

ssh-keygen

cd ~/.ssh
cat id_rsa.pub >authorized_keys
#test
ssh localhost

3.ulimit

vi /etc/security/limits.conf

        * soft noproc 11000
        * hard noproc 11000
        * soft nofile 4100
        * hard nofile 4100

4.hosts

ip1 name1
ip2 name2
  1. ntpd start

service ntpd start
chkconfig ntpd on

6.关闭selinux

/usr/bin/setenforce 修改SELinux的实时运行模式
关闭SELinux:
1、临时关闭(不用重启机器):
setenforce 0                  ##设置SELinux 成为permissive模式
##setenforce 1 设置SELinux 成为enforcing模式
2、修改配置文件需要重启机器:
修改/etc/selinux/config 文件
将SELINUX=enforcing改为SELINUX=disabled

7.安装JDK

rpm -ivh http://192.168.0.11/hdputil/jdklocal-8u151-linux-x64.rpm

#安装路径为:
/usr/java/jdk1.8.0_151

#手动
vi /etc/profile
export JAVA_HOME=/opt/jdk1.8.0_101
export PATH=$JAVA_HOME/bin:$PATH

安装源

下载安装包
下载地址去官网找。

创建repo,命令:

# ll
total 8271672
drwxr-xr-x.  3 ambari-qa users       4096 Jul  3 13:31 ambari
-rw-r--r--.  1 root      root  1619028530 Nov  3 23:13 ambari-2.5.1.0-centos6.tar.gz
drwxr-xr-x.  3 ambari-qa users       4096 Jun  1 07:46 HDP
-rw-r--r--.  1 root      root  6851138150 Nov  3 23:08 HDP-2.6.1.0-centos6-rpm.tar.gz
drwxr-xr-x. 20 root      root        4096 Nov  3 23:42 hdputil

# cd HDP_HOME

# createrepo .`

编辑/etc/yum.repo.d/ambari.repo

[ambari-2.5.0.3]
name=ambari Version - ambari-2.5.0.3
baseurl=http://192.168.0.11/ambari/centos6
gpgcheck=0
gpgkey=http://public-repo-1.hortonworks.com/ambari/centos6/2.x/updates/2.5.0.3/RPM-GPG-KEY/RPM-GPG-KEY-Jenkins
enabled=1
priority=1

编辑/etc/yum.repo.d/HDP.repo

[root@ambari yum.repos.d]# more HDP.repo 
[HDP-2.6]
name=HDP-2.6
baseurl=http://192.168.0.11/HDP/centos6

path=/
enabled=1
gpgcheck=0

编辑/etc/yum.repo.d/HDP.repo

[root@ambari yum.repos.d]# more HDP-UTILS.repo
[HDP-UTILS-1.1.0.21]
name=HDP-UTILS-1.1.0.21
baseurl=http://192.168.0.11/hdputil

path=/
enabled=1
gpgcheck=0

ambari的界面上

http://192.168.2.201/HDP/centos6/2.6.4.0-91/

http://192.168.2.201/HDP-UTIL/

http://192.168.2.201/HDP-GPL/centos6/2.6.4.0-91/

安装ambari server

ambari-server setup

#然后就各种下一步

ambari-server start
#等待启动
#访问http://xxx:8080 

结束

Ambari仓库

注: ambari.hdp的所有服务组件版本都是跟随大版本都的。但是大版本下的补丁是不随大版本号变化的,以补丁的形式合并在所选的大版本里边。
比如: hdp 的phoenix 4.7.0 版本,phoenix 4.7.x 都会合并都4.7.0 里边去,特殊的是4.x.x和 4.1x.x 也都合并到4.7.0里边去了,这就令人费解了。
所以开发的时候只能依赖hdp 官方的maven仓库去做包依赖。如下。

仓库地址:

http://repo.hortonworks.com

pom.xml 配置:

<project>
    <repositories>
        <repository>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>hortonworks.extrepo</id>
            <name>Hortonworks HDP</name>
            <url>http://repo.hortonworks.com/content/repositories/releases</url>
        </repository>

        <repository>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
            <id>hortonworks.other</id>
            <name>Hortonworks Other Dependencies</name>
            <url>http://repo.hortonworks.com/content/groups/public</url>
        </repository>

    </repositories>

</project>

坐标系

WKT - 空间参照系统

一个表示空间参照系统的WKT字串描述了空间物体的测地基准、大地水准面、坐标系统及地图投影。
基础知识:坐标参照系有三种最常见的子类:地心坐标系(geocentric cs、GEOCCS),地理坐标系(geographic cs、GEOGCS),和投影坐标系(projected cs、PROJCS)以及相互之间的关系,可以参考《坐标参照系》。
投影参数内容:Ellipsoid 、 Datum ;Projection,可以参考《地图投影为什么》。


  • 地心坐标系(geocentric cs、GEOCCS) 地心坐标系是以地球质心为原点建立的空间直角坐标系,以x,y,z表示或者以椭球体的中心和此质心重合建立的大地坐标系,大地坐标系一般是用B,L,H表示的
  • 地理坐标系(geographic cs、GEOGCS) 以椭球体为基础建立的坐标系,用经纬度度量坐标 单位:角度
  • 投影坐标系(projected cs、PROJCS) 在特定椭球体基础之上经过地图投影建立的平面坐标系。

WKT表示方法

<coordinate system> = <horz cs> | <geocentric cs> | <vert cs> | <compd cs>
| <fitted cs> | <local cs>
 
<horz cs> = <geographic cs> | <projected cs>
 
<projected cs> = PROJCS["<name>", <geographic cs>, <projection>,
{<parameter>,}* <linear unit> {,<twin axes>}{,<authority>}]
 
<projection> = PROJECTION["<name>" {,<authority>}]
 
<geographic cs> = GEOGCS["<name>", <datum>, <prime meridian>, <angular
unit> {,<twin axes>} {,<authority>}]
 
<datum> = DATUM["<name>", <spheroid> {,<to wgs84>} {,<authority>}]
 
<spheroid> = SPHEROID["<name>", <semi-major axis>, <inverse flattening>
{,<authority>}]
 
<semi-major axis> = <number>
<inverse flattening> = <number>
<prime meridian> = PRIMEM["<name>", <longitude> {,<authority>}]
<longitude> = <number>
<angular unit> = <unit>
<linear unit> = <unit>
<unit> = UNIT["<name>", <conversion factor> {,<authority>}]
<conversion factor> = <number>
<geocentric cs> = GEOCCS["<name>", <datum>, <prime meridian>, <linear unit> {,<axis>,
<axis>, <axis>} {,<authority>}]
 
<authority> = AUTHORITY["<name>", "<code>"]
<vert cs> = VERT_CS["<name>", <vert datum>, <linear unit>, {<axis>,}
{,<authority>}]
 
<vert datum> = VERT_DATUM["<name>", <datum type> {,<authority>}]
 
<datum type> = <number>
<compd cs> = COMPD_CS["<name>", <head cs>, <tail cs> {,<authority>}]
<head cs> = <coordinate system>
<tail cs> = <coordinate system>
<twin axes> = <axis>, <axis>
<axis> = AXIS["<name>", NORTH | SOUTH | EAST | WEST | UP | DOWN | OTHER]
 
<to wgs84s> = TOWGS84[<seven param>]
<seven param> = <dx>, <dy>, <dz>, <ex>, <ey>, <ez>, <ppm>
<dx> = <number>
<dy> = <number>
<dz> = <number>
<ex> = <number>
<ey> = <number>
<ez> = <number>
<ppm> = <number>
 
<fitted cs> = FITTED_CS["<name>", <to base>, <base cs>]
 
<to base> = <math transform>
<base cs> = <coordinate system>
<local cs> = LOCAL_CS["<name>", <local datum>, <unit>, <axis>,
{,<axis>}* {,<authority>}]
 
<local datum> = LOCAL_DATUM["<name>", <datum type> {,<authority>}]

WKT主要关键字解析

  • AUTHORITY
    这个关键字是可选的,表示外部权威的空间参考系统的编码
  • AXIS
    这个关键字主要指定空间参考系统的坐标轴方向,如果没有指定,就使用默认的,默认的指定方向如下:
    地理坐标系统: AXIS[“Lo-”,EAST],AXIS[“Lat”,NORTH]
    投影坐标系统: AXIS[“X”,EAST],AXIS[“Y”,NORTH]
    地心坐标系统: AXIS[“X”,OTHER],AXIS[“Y”,EAST],AXIS[“Z”,NORTH]
  • COMPD_CS
    用于指定一个符合的参考系统,符合参考系统一般由两个坐标系统指定。例如一个3D坐标系统可以由一个水平坐标系统和一个垂直坐标系统复合而成。
  • DATUM
    用于指定一个水平基准面。
  • GEOCCS
    用于指定一个地心坐标系,是一个3D坐标系,X轴的正方向是从地球质心指向赤道和本初子午线的交点,Z轴指向北极方向,Y轴正方向是从地球质心到赤道与东经90度经线的交点。
  • GEOGCS
    用于指定基于经纬度的坐标系统。注意:并不是所有的地理坐标系统都用度来表示单位。
  • LOCAL_CS
    用于指定一个本地的坐标系统。一些坐标系统经常用于CAD系统中
  • PARAMETER
    投影转换的参数及其值。

  • PRIMEM
    用于指定经度度量的本初子午线。

  • PROJCS
    用于指定一个投影坐标系。

  • PROJECTION
    用于指定从地理坐标到投影坐标转换的参数。

  • SPHEROID
    定义一个椭球体,椭球体是地球表面的近似。Spheroid和ellipsoid是同义词。Spheroid一般用于WKT中;而ellipsoid在任何地方使用,都是椭球体的意思。

  • TOWGS84
    用于指示Bursa Wolf变换的七个参数。这七个参数可以近似的从一个基准面到WGS基准面的变换。Bursa Wolf变换只能用于空间直角坐标系之间的变换。

  • UNIT
    用于指定测量使用的单位。在地理坐标系下使用角度。在垂直坐标系下使用线性单位,如米等。

  • VERT_DATUM
    用于指定垂直基准面或者高程测量的方法。

  • VERT_CS
    用于指定一个垂直坐标系统。

坐标系resolution和scale计算

(1) 平面坐标系

Resolution,地面分辨率,类似Spatial Resolution(空间分辨率),我们这里主要关注用象元(pixel size)表示的形式:一个像素(pixel)代表的地面尺寸(米)。以天地图为例,Level为1时,图片大小为256*256(4个Tile),那么赤道空间分辨率为:赤道周长/512。其他纬度的空间分辨率则为 纬度圈长度/512,极端的北极则为0。Level为2时,赤道的空间分辨率为 赤道周长/1024,其他纬度为 纬度圈长度除以1024。很明显,Ground Resolution取决于两个参数,缩放级别Level和纬度latitude ,Level决定像素的多少,latitude决定地面距离的长短。

以LEVEL为1级的时候为前提,取屏幕分辨率为96DPI(像素/英寸)

地面分辨率:一像素代表地面的距离(米),单位为像素/米;

Resolution = 实际距离/屏幕上的像素个数 = 实际距离(米)/512 (像素)

比例尺:屏幕上的距离代表的地面的距离,无单位,仅为一个数值

Scale = 512(像素)/屏幕分辨率(像素/英寸) * 0.0254(米/英寸) /实际距离(米)

运算:天地图取屏幕分辨率为96(像素/英寸)

Resolution * Scale = 1/96 * 0.0254 = 0.0254 /96

Scale = 0.0254 / (96 * Resolution)

Scale = 1 : (96 * Resolution / 0.0254)

(2) 经纬度

经纬度跟平面的思路差不多,不过由于经纬度的表征距离的时候用的是度数,所以在换算的时候,需要把度数
换成米,其换算公司如下:

Scale = 1 : (96 * 2 * Math.PI * 6378137 * resolution / 360 / 0.0254);

- Hive 总:https://cwiki.apache.org/confluence/display/Hive/Home

安装

$ tar -xzvf hive-x.y.z.tar.gz
$ cd hive-x.y.z
$ export HIVE_HOME={{pwd}}
$ export PATH=$HIVE_HOME/bin:$PATH
  

你也可以选择编译hive源码

  $ git clone https://git-wip-us.apache.org/repos/asf/hive.git
  $ cd hive
  $ mvn clean package -Pdist
  $ cd packaging/target/apache-hive-{version}-SNAPSHOT-bin/apache-hive-{version}-SNAPSHOT-bin
  $ ls
  LICENSE
  NOTICE
  README.txt
  RELEASE_NOTES.txt
  bin/ (all the shell scripts)
  lib/ (required jar files)
  conf/ (configuration files)
  examples/ (sample input and query files)
  hcatalog / (hcatalog installation)
  scripts / (upgrade scripts for hive-metastore)
  
  #hive+hadoop一起编译
  mvn clean package -Phadoop-1,dist
  mvn clean package -Phadoop-2,dist

  

运行hive

hive两种模式,第一种是CLI模式直接是shell交互式运行,第二种模式是C-S模式也就是hive客户端-服务端模式hiveserver2

环境变量

#必要的环境变量
  #hadoop home
  $ export HADOOP_HOME=<hadoop-install-dir>

  $ $HADOOP_HOME/bin/hadoop fs -mkdir       /tmp
  $ $HADOOP_HOME/bin/hadoop fs -mkdir       /user/hive/warehouse
  $ $HADOOP_HOME/bin/hadoop fs -chmod g+w   /tmp
  $ $HADOOP_HOME/bin/hadoop fs -chmod g+w   /user/hive/warehouse
  #hive_HOME
  export HIVE_HOME=<hive-install-dir>

第一种模式:运行hive CLI

#直接运行命令
$ $HIVE_HOME/bin/hive

第二种模式

 #初始化模式
 $ $HIVE_HOME/bin/schematool -dbType <db type> -initSchema
 #启动hive Server
 $ $HIVE_HOME/bin/hiveserver2
 #启动hive 客户端
 $ $HIVE_HOME/bin/beeline -u jdbc:hive2://$HS2_HOST:$HS2_PORT
 #默认jdbc:hive2://localhost:10000
 $ $HIVE_HOME/bin/beeline -u jdbc:hive2://
 

HcatLog

#server
$HIVE_HOME/hcatalog/sbin/hcat_server.sh
#client
$ $HIVE_HOME/hcatalog/bin/hcat

WebHCat

$ $HIVE_HOME/hcatalog/sbin/webhcat_server.sh

hive的运行模式

分为两种,一种是mapreduce运行在本地,另外一种是运行在集群上

 hive> SET mapreduce.framework.name=local;
 hive> SET hive.exec.mode.local.auto=false;

DDL

详细参考DDL


hive> CREATE TABLE pokes (foo INT, bar STRING);
#分区的意思是hdfs存储时候的物理目录按照分区字符串来存取。
hive> CREATE TABLE invites (foo INT, bar STRING) PARTITIONED BY (ds STRING);
hive> CREATE TABLE t_hive (a int, b int, c int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
#表描述
 hive> SHOW TABLES;
 hive> SHOW TABLES '.*s';
 hive> DESCRIBE invites;
 
 #alter
 hive> ALTER TABLE events RENAME TO 3koobecaf;
 hive> ALTER TABLE pokes ADD COLUMNS (new_col INT);
 hive> ALTER TABLE invites ADD COLUMNS (new_col2 INT COMMENT 'a comment');
 hive> ALTER TABLE invites REPLACE COLUMNS (foo INT, bar STRING, baz INT COMMENT 'baz replaces new_col2');
 #drop
 DROP TABLE pokes;

DML

详细参考DML
LOCAL 代表着文件在本地磁盘上,如果没有LOCAL那么代表着文件在HDFS上
OVERWRITE 代表如果记录存在那么覆盖,如果没有这个关键字在那么append上去

#本地文件
hive> LOAD DATA LOCAL INPATH './examples/files/kv1.txt' OVERWRITE INTO TABLE pokes;
#两个partition
hive> LOAD DATA LOCAL INPATH './examples/files/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');
hive> LOAD DATA LOCAL INPATH './examples/files/kv3.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-08');
#HDFS
hive> LOAD DATA INPATH '/user/myname/kv2.txt' OVERWRITE INTO TABLE invites PARTITION (ds='2008-08-15');


SQL

详细:LanguageManual+Select

SELECT

 hive> SELECT a.foo FROM invites a WHERE a.ds='2008-08-15';
 #HDFS
 hive> INSERT OVERWRITE DIRECTORY '/tmp/hdfs_out' SELECT a.* FROM invites a WHERE a.ds='2008-08-15';
 #本地
 hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/local_out' SELECT a.* FROM pokes a;
 
   hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a;
  hive> INSERT OVERWRITE TABLE events SELECT a.* FROM profiles a WHERE a.key < 100;
  hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/reg_3' SELECT a.* FROM events a;
  hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_4' select a.invites, a.pokes FROM profiles a;
  hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT COUNT(*) FROM invites a WHERE a.ds='2008-08-15';
  hive> INSERT OVERWRITE DIRECTORY '/tmp/reg_5' SELECT a.foo, a.bar FROM invites a;
  hive> INSERT OVERWRITE LOCAL DIRECTORY '/tmp/sum' SELECT SUM(a.pc) FROM pc1 a;
  
  

Group BY

#注意两种查询方式
hive> FROM invites a INSERT OVERWRITE TABLE events SELECT a.bar, count(*) WHERE a.foo > 0 GROUP BY a.bar;
hive> INSERT OVERWRITE TABLE events SELECT a.bar, count(*) FROM invites a WHERE a.foo > 0 GROUP BY a.bar;

join

  hive> FROM pokes t1 JOIN invites t2 ON (t1.bar = t2.bar) INSERT OVERWRITE TABLE events SELECT t1.bar, t1.foo, t2.foo;

MULTITABLE INSERT

  FROM src
  INSERT OVERWRITE TABLE dest1 SELECT src.* WHERE src.key < 100
  INSERT OVERWRITE TABLE dest2 SELECT src.key, src.value WHERE src.key >= 100 and src.key < 200
  INSERT OVERWRITE TABLE dest3 PARTITION(ds='2008-04-08', hr='12') SELECT src.key WHERE src.key >= 200 and src.key < 300
  INSERT OVERWRITE LOCAL DIRECTORY '/tmp/dest4.out' SELECT src.value WHERE src.key >= 300;

STREAMING

hive> FROM invites a INSERT OVERWRITE TABLE events SELECT TRANSFORM(a.foo, a.bar) AS (oof, rab) USING '/bin/cat' WHERE a.ds > '2008-08-09';

Hive 命令模式

Hbase的思考

没有限制,但是需要考虑一些问题:

锁力度

当你操作一行数据的时候,这个regionserver 会对这个行进行暂时锁定,来进行操作,

从好的方面看,我们可以并发的进行原子读操作,或者压根不能修改操作。除非可以可以容忍误差(部分更新,数据时效不敏感)

在弊的方面看,这意味着单个行内的吞吐量的写入操作被限制(可能几百每秒)。

Region的分布式性能

对一个row进行操作的负载均衡和分布式单位都在一个region上,所以这个region到底有多忙,他也只会通过这台机器提供服务。如果是多行那么就可以做多台服务进行一个负载均衡。

Bugs

在一些早起版本有些bug,他会突然加载反序列化整行数据到内存中,所以行column非常多(100MB)的话就会导致OOM, 这些bug可能已经解决了吧?regionserver也会更聪明的选择需要的column进行加载。

这个是需要明确的。

总结

如果你不需要做原子操作,那么可能最好的方式是设计一个高表模型来实现的逻辑

下载


官方下载地址:
http://www.oracle.com/technetwork/java/javase/downloads/index.html

目前是JDK 9.0.1,随便下无障碍

image.png

Oracle JDK9 文档

http://docs.oracle.com/javase/9/index.html

安装

正常安装,如果是windows OS需要配置环境变量正常配置

JAVA_HOME=jdk安装路径
JRE_HOME=jre安装路径
PATH= .;%JAVA_HOME%\bin;%JRE_HOME%\bin
CLASSPATH=.;%JAVA_HOME%\lib;%JRE_HOME%\lib

验证

出现下面信息基本安装成功

leombp:bin Leo$ java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)

结构

其中
bin : 下是java命令不变只不过新增了几个新命令,如下:jshelljavawsjcontroljdeprscanjhsdb jimagejlinkjmodjweblauncher
jmod : 是模块目录
lib : jar包 和 库包

#以下为JDK9主要修改部分(删除了很多文件和文件夹,为了看的更清楚)
.
├── bin
│   ├── appletviewer
│   ├── idlj
│   ├── jar
│   ├── jarsigner
│   ├── java
│   ├── javac
│   ├── javadoc
│   ├── javah
│   ├── javap
│   ├── javapackager
│   ├── javaws
│   ├── jcmd
│   ├── jconsole
│   ├── jcontrol
│   ├── jdb
│   ├── jdeprscan
│   ├── jdeps
│   ├── jhsdb
│   ├── jimage
│   ├── jinfo
│   ├── jjs
│   ├── jlink
│   ├── jmap
│   ├── jmc
│   ├── jmod
│   ├── jps
│   ├── jrunscript
│   ├── jshell
│   ├── jstack
│   ├── jstat
│   ├── jstatd
│   ├── jweblauncher
│   ├── keytool
│   ├── orbd
│   ├── pack200
│   ├── policytool
│   ├── rmic
│   ├── rmid
│   ├── rmiregistry
│   ├── schemagen
│   ├── serialver
│   ├── servertool
│   ├── tnameserv
│   ├── unpack200
│   ├── wsgen
│   ├── wsimport
│   └── xjc
├── conf
├── include
├── jmods
│   ├── java.activation.jmod
│   ├── java.base.jmod
│   ├── java.compiler.jmod
│   ├── java.corba.jmod
│   ├── java.datatransfer.jmod
│   ├── java.desktop.jmod
│   ├── java.instrument.jmod
│   ├── java.jnlp.jmod
│   ├── java.logging.jmod
│   ├── java.management.jmod
│   ├── java.management.rmi.jmod
│   ├── java.naming.jmod
│   ├── java.prefs.jmod
│   ├── java.rmi.jmod
│   ├── java.scripting.jmod
│   ├── java.se.ee.jmod
│   ├── java.se.jmod
│   ├── java.security.jgss.jmod
│   ├── java.security.sasl.jmod
│   ├── java.smartcardio.jmod
│   ├── java.sql.jmod
│   ├── java.sql.rowset.jmod
│   ├── java.transaction.jmod
│   ├── java.xml.bind.jmod
│   ├── java.xml.crypto.jmod
│   ├── java.xml.jmod
│   ├── java.xml.ws.annotation.jmod
│   ├── java.xml.ws.jmod
│   ├── javafx.base.jmod
│   ├── javafx.controls.jmod
│   ├── javafx.deploy.jmod
│   ├── javafx.fxml.jmod
│   ├── javafx.graphics.jmod
│   ├── javafx.media.jmod
│   ├── javafx.swing.jmod
│   ├── javafx.web.jmod
│   ├── jdk.accessibility.jmod
│   ├── jdk.attach.jmod
│   ├── jdk.charsets.jmod
│   ├── jdk.compiler.jmod
│   ├── jdk.crypto.cryptoki.jmod
│   ├── jdk.crypto.ec.jmod
│   ├── jdk.deploy.controlpanel.jmod
│   ├── jdk.deploy.jmod
│   ├── jdk.dynalink.jmod
│   ├── jdk.editpad.jmod
│   ├── jdk.hotspot.agent.jmod
│   ├── jdk.httpserver.jmod
│   ├── jdk.incubator.httpclient.jmod
│   ├── jdk.internal.ed.jmod
│   ├── jdk.internal.jvmstat.jmod
│   ├── jdk.internal.le.jmod
│   ├── jdk.internal.opt.jmod
│   ├── jdk.internal.vm.ci.jmod
│   ├── jdk.jartool.jmod
│   ├── jdk.javadoc.jmod
│   ├── jdk.javaws.jmod
│   ├── jdk.jcmd.jmod
│   ├── jdk.jconsole.jmod
│   ├── jdk.jdeps.jmod
│   ├── jdk.jdi.jmod
│   ├── jdk.jdwp.agent.jmod
│   ├── jdk.jfr.jmod
│   ├── jdk.jlink.jmod
│   ├── jdk.jshell.jmod
│   ├── jdk.jsobject.jmod
│   ├── jdk.jstatd.jmod
│   ├── jdk.localedata.jmod
│   ├── jdk.management.agent.jmod
│   ├── jdk.management.cmm.jmod
│   ├── jdk.management.jfr.jmod
│   ├── jdk.management.jmod
│   ├── jdk.management.resource.jmod
│   ├── jdk.naming.dns.jmod
│   ├── jdk.naming.rmi.jmod
│   ├── jdk.net.jmod
│   ├── jdk.pack.jmod
│   ├── jdk.packager.jmod
│   ├── jdk.packager.services.jmod
│   ├── jdk.plugin.dom.jmod
│   ├── jdk.plugin.jmod
│   ├── jdk.plugin.server.jmod
│   ├── jdk.policytool.jmod
│   ├── jdk.rmic.jmod
│   ├── jdk.scripting.nashorn.jmod
│   ├── jdk.scripting.nashorn.shell.jmod
│   ├── jdk.sctp.jmod
│   ├── jdk.security.auth.jmod
│   ├── jdk.security.jgss.jmod
│   ├── jdk.snmp.jmod
│   ├── jdk.unsupported.jmod
│   ├── jdk.xml.bind.jmod
│   ├── jdk.xml.dom.jmod
│   ├── jdk.xml.ws.jmod
│   ├── jdk.zipfs.jmod
│   ├── oracle.desktop.jmod
│   └── oracle.net.jmod
├── legal
├── lib
│   ├── ant-javafx.jar
│   ├── classlist
│   ├── ct.sym
│   ├── deploy
│   ├── deploy.jar
│   ├── fontconfig.bfc
│   ├── fontconfig.properties.src
│   ├── fonts
│   ├── java.jnlp.jar
│   ├── javafx-swt.jar
│   ├── javafx.properties
│   ├── javaws.jar
│   ├── jdk.deploy.jar
│   ├── jdk.javaws.jar
│   ├── jdk.plugin.dom.jar
│   ├── jdk.plugin.jar
│   ├── jfr
│   │   ├── default.jfc
│   │   └── profile.jfc
│   ├── jli
│   │   └── libjli.dylib
│   ├── jrt-fs.jar
│   ├── jspawnhelper
│   ├── jvm.cfg
│   ├── libattach.dylib
│   ├── libawt.dylib
│   ├── libawt_lwawt.dylib
│   ├── libbci.dylib
│   ├── libcmm.dylib
│   ├── libdcpr.dylib
│   ├── libdecora_sse.dylib
│   ├── libdeploy.dylib
│   ├── libdt_socket.dylib
│   ├── libfontmanager.dylib
│   ├── libfxplugins.dylib
│   ├── libglass.dylib
│   ├── libglib-lite.dylib
│   ├── libgstreamer-lite.dylib
│   ├── libinstrument.dylib
│   ├── libj2gss.dylib
│   ├── libj2pcsc.dylib
│   ├── libj2pkcs11.dylib
│   ├── libjaas_unix.dylib
│   ├── libjava.dylib
│   ├── libjavafx_font.dylib
│   ├── libjavafx_font_t2k.dylib
│   ├── libjavafx_iio.dylib
│   ├── libjavajpeg.dylib
│   ├── libjawt.dylib
│   ├── libjdwp.dylib
│   ├── libjfxmedia.dylib
│   ├── libjfxmedia_avf.dylib
│   ├── libjfxwebkit.dylib
│   ├── libjimage.dylib
│   ├── libjsig.dylib
│   ├── libjsound.dylib
│   ├── libkcms.dylib
│   ├── liblcms.dylib
│   ├── libmanagement.dylib
│   ├── libmanagement_agent.dylib
│   ├── libmanagement_ext.dylib
│   ├── libmlib_image.dylib
│   ├── libnet.dylib
│   ├── libnio.dylib
│   ├── libnpjp2.dylib
│   ├── libosx.dylib
│   ├── libosxapp.dylib
│   ├── libosxkrb5.dylib
│   ├── libosxsecurity.dylib
│   ├── libosxui.dylib
│   ├── libprefs.dylib
│   ├── libprism_common.dylib
│   ├── libprism_es2.dylib
│   ├── libprism_sw.dylib
│   ├── librm.dylib
│   ├── librmi.dylib
│   ├── libsaproc.dylib
│   ├── libsplashscreen.dylib
│   ├── libsunec.dylib
│   ├── libt2k.dylib
│   ├── libunpack.dylib
│   ├── libverify.dylib
│   ├── libzip.dylib
└── release

202 directories, 1172 files

该教程是新手版,完全不懂Gis。直接哪里啊就可以用了。

使用乐太地图下载器

附下载地址破解版
链接:https://pan.baidu.com/s/1nwLhXod 密码:ne38

下载Google地图

image.png

注意红色部分。需要选择,就按照google自己的方式进行存储。不用修改

下载下来如下目录:

级别/列/行.png

image.png

发布服务

讲下载下来的目录放到tomcat中:
不用war啥的复杂的东西,直接在tomcat的webapps 中创建一个目录tiles让后将刚才的下载的瓦片目录拷贝过来,然后请求就好了。
目录如下:
image.png

好了看见了,整个目录就这样了。启动tomcat

然后请求: http://localhost:8080/tiles/googleworld/{z}/{x}/{y}.png
将z/x/y 换成你的级别,行列号,就可以请求到一个地图分片了。

如何使用这个离线地图Demo

    <!DOCTYPE html>  
    <html xmlns="http://www.w3.org/1999/xhtml">  
    <head>  
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
        <title></title>  
        <link rel="stylesheet" href="https://openlayers.org/en/v4.2.0/css/ol.css" type="text/css">  
        <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->  
        <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>  
        <script src="https://openlayers.org/en/v4.2.0/build/ol.js"></script>  
        
        <!--<script type="text/javascript" src="js/ol.js" ></script>-->
        <!--<script type="text/javascript" src="js/p.js" ></script>-->
        
    </head>  
    <body>  
        <div id="googleMap" style="width: 100%"></div>
<script>
    // google地图层
    var googleMapLayer = new ol.layer.Tile({
        source: new ol.source.XYZ({
            //url:'http://www.google.cn/maps/vt/pb=!1m4!1m3!1i{z}!2i{x}!3i{y}!2m3!1e0!2sm!3i345013117!3m8!2szh-CN!3scn!5e1105!12m4!1e68!2m2!1sset!2sRoadmap!4e0'
             url:'http://localhost:8080/tiles/googleworld/{z}/{x}/{y}.png'
        })
    });

    // 创建地图
  var map = new ol.Map({
        layers: [
            googleMapLayer
        ],
        view: new ol.View({
            center: [108.4250, 34.0890],
            projection: 'EPSG:4326',
            zoom: 4
        }),
        target: 'googleMap'
  });
</script> 
    </body>  
    </html>  

最主要的一项内容

就是研究Openlayers4 如何做业务了。
给个链接:这是一个各种个地图的加载说明,这个地址里边的其他文章也可以看看。

http://weilin.me/ol3-primer/ch05/05-03.html

Mysql

$ mysql -u root -p
Enter password:

mysql> use mysql

#mysql> GRANT ALL ON *.* to root@'192.168.1.4' IDENTIFIED BY 'your-root-password'; 


mysql> GRANT ALL ON *.* to root@'%' IDENTIFIED BY 'root'; 

mysql> FLUSH PRIVILEGES;

环境:

spark1.6
anaconda:python2.7

创建conda 虚拟环境

  1. 安装anaconda啦

  1. 下载Anaconda 安装包可以到 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/

  2. 由于国内镜像访问比较慢所以更换为清华的 Anaconda 仓库的镜像,运行以下命令进行更换:

    conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
    conda config --set show_channel_urls yes
    

Conda 三方源

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/



准备虚拟环境
------

创建一个tensorflowenv 的虚拟环境:

conda create -n tensorflowenv tensorflow

安装你所需要的其他的包

conda install -n tensorflowenv [other package]

查找打包你的所创建的虚拟包

我的conda_home=/opt/anaconda2

tar -cvf /opt/anaconda2/envs/tensorflowenv.tar /opt/anaconda2/envs/tensorflowenv
gzip /opt/anaconda2/envs/tensorflowenv.tar

OK.至此你已经将spark TensorFlow的环境安装好了。
可以将这个包,移植解压到其他的机器上了。
`注意:环境路径需要保持一致,否则没法配置python 路径`

运行你的python spark程序
------------
请注意如果你需要使用python 读取或者写入使用hdfs的文件那么你需要江hdfs 文件系统`mount`到每个`spark executor`的节点去。你过有别的好的办法可以告诉我。(这块需要开启hdfs的`nfs gateway` )
**命令:**`mount.nfs 192.168.1.111:/ /mnt/hdfs`

pyspark 提交任务

spark-submit \
--master yarn \
--deploy-mode cluster \
--conf spark.pyspark.python=/opt/anaconda2/envs/tensorflowenv/bin/python \
--conf spark.pyspark.driver.python=/opt/anaconda2/envs/tensorflowenv/bin/python \
tf_spark.py /mnt/hdfs/user/spark/img/L11.img /mnt/hdfs/user/spark/output


结束
---------
1. 只需要指定`python`环境就好了,因为他的原理是java 拉起python进程进行操作的,所以python环境是可以指定的。

2. 因为很多`C/C++`编译的包,已经封装了读写本地文件的方法,所以没法使用`python`直接读取hdfs文件所以才要mount到本地







Spring boot batch

1.简介

Spring boot batch 一共有两种任务运行方式。

  1. 使用tasklet 只执行一个Tasklet.execute() 然后你可以使用jobs.start(xx).next(xx2).next(xx3);

  2. 使用 this.step.chunck().reader().processor().writer().build();

2.总结:

使用完之后感觉麻烦、不好用(可能我还没有理解到他的精髓),然后我用CommandLineRunner@Order(1)实现了任务的顺序调用问题。

3.下面是Spring boot batch的例子:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.data.mongodb.core.MongoTemplate;

/**
 * 1. 使用tasklet 只执行一个Tasklet.execute() 然后你可以使用jobs.start(xx).next(xx2).next(xx3);
 * 2. 使用 this.step.chunck().reader().processor().writer().build();
 */
@SpringBootApplication
@EnableBatchProcessing
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class SpiderBatchApplication {

    private static final Logger logger = LoggerFactory.getLogger(SpiderBatchApplication.class);

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    MongoTemplate mongoTemplate;

    @Bean
    protected Tasklet tasklet() {

        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution,
                    ChunkContext context) {
                logger.info("======tasklet");
                return RepeatStatus.FINISHED;
            }
        };

    }

    @Bean
    public Job job() throws Exception {
        logger.info("======job");
        return this.jobs.get("job").start(step1()).build();
    }

    @Bean
    protected Step step1() throws Exception {
        logger.info("======step1");
        //1. 第一种方式
        //this.steps.get("step1").chunk(10).reader(null).processor(null).writer(null).build();
        //2. 第二种方式
        return this.steps.get("step1").tasklet(tasklet()).build();
    }

    /**
     * job->step->tasklet
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // System.exit is common for Batch applications since the exit code can be used to
        // drive a workflow
        logger.info("======================");
        System.exit(SpringApplication
                .exit(SpringApplication.run(SpiderBatchApplication.class, args)));
    }

}

**`Spring boot`** 的最基本的操作就是执行一个进程 也就是 **`CommandLineRunner`**。如果要使用`spring batch` 那么就可以研究下`spring boot batch` 参考另一篇博文

CommandLineRunner.java

你需要做的就是实现run() 方法,并不是一个线程
你可以使用Order(num)来实现流程的控制。
原型为下:

#CommandLineRunner.java 

public interface CommandLineRunner {
    void run(String... var1) throws Exception;
}

#ApplicationRunner.java
public interface ApplicationRunner {
    void run(ApplicationArguments var1) throws Exception;
}

下面是CommandLineRunner的例子:

  1. SpiderBatchApplication.java

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
    import org.springframework.context.annotation.Bean;
    @EnableAutoConfiguration
    @SpringBootApplication
    public class SpiderBatchApplication {
    private static final Logger logger = LoggerFactory.getLogger(SpiderBatchApplication.class);
    /**
    *
    * @param args
    * @throws Exception
    */
    public static void main(String[] args) throws Exception {
    // System.exit is common for Batch applications since the exit code can be used to
    // drive a workflow
    logger.info("======================");
    System.exit(SpringApplication
    .exit(SpringApplication.run(SpiderBatchApplication.class, args)));
    }
    }
  2. Task1.java

    import org.springframework.boot.ApplicationArguments;
    import org.springframework.boot.ApplicationRunner;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    @Component
    @Order(2)
    public class Task1 implements CommandLineRunner {
    @Override
    public void run(String... strings) throws Exception {
    System.out.println("task11111111111");
    }
    }
  3. Task2.java

    
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    /**
    * Created with IntelliJ IDEA.
    * User: leo
    * Date: 2017/11/10
    * Time: 10:15
    * To change this template use File | Settings | File Templates.
    */
    @Component
    @Order(1)
    public class Task2 implements CommandLineRunner {
    @Override
    public void run(String... strings) throws Exception {
    System.out.println("task2222222222");
    }
    }

Sqoop 概要

Sqoop是Hadoop和关系数据库服务器之间传送数据的一种工具。链接各种DBMS到Hadoop的工具。
看图:
image.png

说白了Sqoop就两个主要功能:

  • 导入(to hadoop)
  • 导出(to dbms)

次要功能

  • 任务Job 提交

其他工具类型:

  • list-tables
  • list-databases
  • eval 查询用户自定义
  • codegen 生成一个Dao

Sqoop的安装

  • Java(省了)
  • Hadoop的安装(Hdfs、Yarn?)(省了)
  • sqoop(如下)
#sqoop
export SQOOP_HOME=/usr/lib/sqoop 
export PATH=$PATH:$SQOOP_HOME/bin
cd $SQOOP_HOME/conf
$ mv sqoop-env-template.sh sqoop-env.sh
export HADOOP_COMMON_HOME=/usr/local/hadoop 
export HADOOP_MAPRED_HOME=/usr/local/hadoop

#依赖各种dbms的jdbc包(Oracle、Mysql.....)
tar -zxf mysql-connector-java-5.1.30.tar.gz
cd mysql-connector-java-5.1.30
mv mysql-connector-java-5.1.30-bin.jar /usr/lib/sqoop/lib

#验证sqoop
$ cd $SQOOP_HOME/bin
$ sqoop-version

Sqoop导入