ELK: Data Modeling

数据建模

1.英文为Data Modeling,为创建数据模型的过程
2.数据模型(Data Model):  
<1>对现实世界进行抽象描述的一种工具和方法  
<2>通过抽象的实体及实体之间联系的形式去描述业务规则,从而实现对现实世界的映射

数据建模规则

1.概念模型:确定系统的核心需求和范围边界,设计实体和实体间的关系
2.逻辑模型:进一步梳理也无需求,确定每个实体的属性、关系和约束等
3.物理模型:  
<1>结合具体的数据库产品,在满足业务读写性能等需求的前提下确定最终的定义 <2>Mysql、MongoDB、elasticsearch等  
<3>第三范式

ES中的数据建模

ES是基于Lucene以倒排索引为基础实现的存储体系,不遵循关系型数据库中的范式约定

Mapping字段的相关设置

1.enabled:  
<1> true | false  
<2>仅存储,不做搜索或聚合分析
2.index:  
<1> true | false  
<2>是否构建倒排索引
3.index_options  
<1> docs | freqs | positions | offsets  
<2>存储倒排索引的哪些信息
4.norms  
<1>true | false  
<2>是否存储归一化相关参数, 如果字段仅用与过滤和聚合分析
5.doc_values  
<1>true | false  
<2>是否启用doc_values, 用于排序和聚合分析  
6.field_data  
<1>true | false  
<2>是否为text类型启用fielddata, 实现倒排和聚合分析
7.store  
<1>false | true  
<2>是否存储该字段值
8.coerce  
<1>true | false  
<2>是否开启自动类型转换功能, 比如字符串转为数字,浮点转为整型
9.multifields多字段  
<1>灵活使用多字段特性来解决多样的业务需求
10.dynamic  
<1>true | false | strict  
<2>控制mapping自动更新
11.date_detection  
<1>true | false  
<2>是否自动识别日期类型

Mapping字段属性的设定流程

1.是何种类型
2.是否需要检索
3.是否需要排序和聚合分析
4.是否需要另行存储

是何种类型

1.字符串类型:需要分词则设定为text类型,否则设置为keyword类型
2.枚举类型:基于性能考虑将其设定为keyword类型,即便该数据为整型
3.数值类型:尽量选择贴近的类型,比如byte即可表示所有数值时,即选用byte,不要用long
4.其他类型:比如布尔类型、日期、地理位置数据等

是否需要检索

1.完全不需要检索、排序、聚合分析的字段:enabled设置为false
2.不需要检索的字段:index设置为false
3.需要检索的字段,可以通过如下配置设定需要的存储粒度:  
<1>index_options结合需要设定  
<2>norms不需要归一化数据时即可关闭

是否需要排序和聚合分析

不需要排序或者聚合分析功能:  
<1>doc_values设定为false  
<2>fielddata设定为false

是否需要另行存储

是否需要专门存储当前字段的数据?  
<1>store设定为true,即可存储该字段的原始内容(与_source中的不想关)  
<2>一般结合_source的enabled设定为false时使用

关联关系处理

es不擅长处理关系型数据库中的关联关系,比如文章表blog与评论表comment之间通过blog_id关联,在es中可以通过如下两种手段变相解决:
<1>Nested Object
<2>Parent/Child

Nested Object方式处理关联关系

1.不指定为nested的话,将存储为Object Array
2.Nested Object Array是将每一个指定为nested类型的数据独立存储

Parent/Child方式处理关联关系

es提供了类似关系数据库中join的实现方式,使用join数据类型实现

Parent/Child常见的query语法

常见query语法包括如下几种:
1.parent_id返回某父文档的子文档
2.has_child返回包含某子文档的父文档
3.has_parent返回包含某父文档的子文档

parent_id

parent_id查询:返回某父文档的子文档

has_child

返回包含某子文档的父文档

has_parent

has_parent查询:返回包含某父文档的子文档

Nested Object vs Parent/Child

Nested Object:
优点:文档存储在一起,因此可读性能高
缺点:更新父或子文档时需要更新整个文档
场景:子文档偶尔更新,查询频繁
Parent/Child:
优点:父子文档可以独立更新,互补影响
缺点:为了维护join的关系,需要占用部分内存,可读性能较差
场景:子文档更新频繁

Reindex

1.指重建所有数据的过程,一般发生在如下情况:  
<1>mapping设置变更,比如字段类型变化、分词器字典更新等  
<2>index设置变更,比如分片数更改等  
<3>迁移数据
2.es提供了现成的API用于完成该工作  
<1>_update_by_query在现有索引上重建  
<2>_reindex在其他索引上重建

Reindex-_update_by_query

Reindex-_reindex

Reindex-Task

1.数据重建的时间受源索引文档规模的影响,当规模越大时,所需时间越多,此时需要通过设定url参数wait_for_completion为false来异步执行,ES以task来描述此类执行任务
2.ES提供了Task API来查看任务的执行进度和相关数据

数据模型版本管理

对Mapping进行版本管理
<1>包含在代码或者以专门的文件进行管理,添加好注释,并加入Git等版本管理仓库中,方便回顾
<2>为每个增加一个metadata字段,在其中维护一些文档相关的元数据,方便对数据进行管理

防止字段过多

1.字段过多主要有如下的坏处: 
<1>南与维护,当字段成千上百时,基本很难有人能明确知道每个字段的含义 
<2>mapping的信息存储在cluster state里面,过多的字段会导致mapping过大,最终导致更新变慢
2.通过设置index.mapping.total_fields.limit可以限定索引中最大字段数,默认是1000
3.可以通过key/value的方式解决字段过多的问题,但并不完美
4.一般字段过多的原因是由于没有高质量的数据建模导致的,比如dynamic设置为true
5.考虑拆分成多个索引来解决问题

Key/Value方式详解

1.可以极大减少Field数目,但也有一些明显的坏处 
<1>query语句复杂度飙升,且有一些可能无法实现,比如聚合分析相关的 
<2>不利于在Kibana中做可视化分析

ELK: Elasticsearch Inverted Index And Analyzer

搜索引擎:

正排索引:文档Id到文档内容、单词的关联关系
倒排索引:单词到文档Id的关联关系

倒排索引:

倒排索引是搜索引擎的核心,主要包括两部分:
单词词典(Term Dictionary)
倒排列表(Posting List)

单词辞典:

单词词典是倒排索引的重要组成:
记录所有文档的单词,一般都比较大
记录单词到倒排列表的关联信息

倒排列表:

1.倒排列表(Posting List)记录了单词对应的文档集合,由倒排索引项(Posting)组成
2.倒排索引项主要包含如下信息:
<1>文档Id,用于获取原始信息
<2>单词频率(TF, Term Frequency), 记录该单词在该文档中出现次数, 用于后续相关性算分
<3>位置(Position), 记录单词在文档中的分词位置(多个), 用于做词语搜索(Phrase Query)
<4>偏移(Offset), 记录单词在文档的开始和结束位置, 用于做高亮显示

es存储的是一个JSON格式的文档, 其中包含多个字段, 每个字段都会有自己的倒排索引.

分词:

将文本分成一系列单词(term or token)的过程叫做分词, 也可以叫做文本分析, 在es里面称为Analysis。

分词器:

1.分词器是es中专门处理分词的组件, 英文为Analyzer, 它的组成如下:
<1>Character Filters:针对原始文本进行处理, 比如去除html特殊标记
<2>Tokenizer:将原始文本按照一定规则切分为单词
<3>Token Filters:针对tokenizer处理的单词再加工,比如转成小写、删除或新增等处理
2.Character Fileters->Tokenizer->Token Filters

Analyzer API:

预定义分词器:

Standard Analyzer:默认分词器;特性为:按词切分,支持多语言;小写处理
Simple Analyzer:特性为:按照非字母切分;小写处理
Whitespace Analyzer:特性为:按空格切分
Stop Analyzer:Stop Word指语气助词等修饰性的词语,比如the、an、的、这等等;特性为:相比Simple Analyzer多了Stop Word的处理
Keyword Analyzer:特性为:不分词, 直接将输入作为一个单词输出
Pattern Analyzer:特性为:通过正则表达式自定义分隔符;默认是\W+, 即非字符的符号作为分隔符
Language Analyzer:提供30多种常见语言的分词

中文分词:

1.难点:汉语中没有一个形式上的分界符;上下文不同,分词结果迥异,比如交叉歧义问题.
2.常见分词系统:IK, jieba
3.基于自然语言处理的分词系统: Hanlp, THULAC

自定义分词:

当自带的分词无法满足需求时, 可以自定义分词:通过自定义Character Filters、 Tokenizer和Token Filter实现。

Character Filters:

1.在Tokenizer之前对原始文本进行处理, 比如增加、删除或替换字符等
自带的功能有:HTML strip去除html标签和转换html实体;Mapping进行字符替换操作;Pattern Replace进行正则匹配替换
2.会影响后续tokenizer解析的postion和offset信息

Tokenizer:

将原始文本按照一定规则切分为单词(term or token)
自带功能如下:
standard 按照单词进行分割;
letter 按照非字符类进行分割;
whitespace 按照空格进行分割;
UAX URL Email 按照standard分割,但不会分割邮箱和url;
NGram 和 Edge NGram 连词分割;
Path Hierarchy 按照文件路径进行切割

Token Filters:

1.对于tokenizer输出的单词(term)进行增加、删除、修改等操作
2.自带的如下:
lowercase 将所有term转换为小写;
stop 删除stop words;
NGram 和 Edge NGram 连词分割;
Synonym 添加近义词的term

自定义分词的api

分词使用说明

分词会在如下两个时机使用:
1.创建或更新文档时(Index Time), 会对相应的文档进行分词处理
2.查询时(Search Time), 会对查询语句进行分词

索引时分词

查询时分词:

一般不需要特别指定查询时分词器,直接食用索引时分词器即可,否则会出现无法匹配的情况.

建议:

1.明确字段是否需要分词,不需要分词的字段就将type设置为keyword,可以节省空间和提高写性能
2.善用_analyze API, 查看文档的具体分词结果
3.动手测试

Install Nginx By Compile Sources

环境:阿里云 CentOS7.3

1.安装pcre
安装在/usr/local/下:
cd /usr/local
获取pcre包,注意不要获取pcre2的包,否则编译Nginx将出错:
网址:https://ftp.pcre.org/pub/pcre/
wget https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz
解压pcre压缩包:
tar -zxvf pcre-8.43.tar.gz
进入pcre目录:
cd pcre-8.43
对环境进行配置检查:
./configure
编译并安装:
make && make install

2.安装zlib
安装在/usr/local/下:
cd /usr/local
获取zlib:
网址:http://zlib.net/
wget http://zlib.net/zlib-1.2.11.tar.gz
解压zlib包:
tar -zxvf zlib-1.2.11.tar.gz
进入zlib目录:
cd zlib-1.2.11
对环境进行配置检查:
./configure
编译并安装:
make && make install

3.安装openssl
安装在/usr/local/下
cd /usr/local
获取openssl:
网址:https://www.openssl.org/source/
wget https://www.openssl.org/source/openssl-1.1.1c.tar.gz
解压openssl包:
tar -zxvf openssl-1.1.1c.tar.gz
进入openssl目录:
cd openssl-1.1.1c
对环境配置检查:
./config
编译并安装:
make && make install

4.安装nginx:
安装在/usr/local/下:
cd /usr/local
获取nginx:
网址:http://nginx.org/en/download.html
wget http://nginx.org/download/nginx-1.16.1.tar.gz
解压nginx:
tar -zxvf nginx-1.16.1.tar.gz
进入nginx目录:
cd nginx-1.16.1
对环境进行配置检查:
./configure –prefix=/usr/local/nginx –with-pcre=/usr/local/pcre-8.43 –with-zlib=/usr/local/zlib-1.2.11 –with-openssl=/usr/local/openssl-1.1.1c
进行编译安装:
make && make install

开启nginx:
/usr/local/nginx/sbin/nginx
关闭nginx:
/usr/local/nginx/sbin/nginx -s stop
重启nginx:
/usr/local/nginx/sbin/nginx -s restart
通过浏览器浏览,输入ip地址。

DL-池化层

池化层通常用于在特征图中提取主要特征。一般有平均池化、最大池化。池化会缩小特征图,可以通过添加池化后特征图的深度进行弥补。

池化层具有不变性。对于2×2的池化来说,如果某个特征在2×2的区域中平移,池化层所提取的特征将会是一样的。尺度的大小也不会影响最后池化所提取到的特征。因此,池化层具有平移不变性和尺度不变性。

TensorFlow:基础_会话

内容:Session

一个会话的典型流程分为3步:
(1)创建会话
(2)运行会话
(3)关闭会话

创建会话

Session构造方法的输入参数

会话的主要配置参数

例:希望在没有GPU时将计算任务放到CPU上执行,并通过日志验证放置情况

运行会话

Session.run方法的输入参数

用例

代码:

结果:

关闭会话

显式关闭
sess.close()
隐式关闭
with tf.Session() as sess:
sess.run()

交互式会话InteractiveSession

交互式会话提供类似shell的交互式编程环境。交互式会话和普通回话的主要区别是:交互式会话实例创建后,该实例被注册为默认会话。因此,如果后续需要使用Tensor.eval或Operation.run求解张量、执行操作可以直接使用而不需要借助with语句块。最后还是需要通过显式关闭会话:InteractiveSession.close

用例

代码:

结果:

30.0