mysql学习笔记(13)之mycat切分规则与es基础


内容来源为六星教育,这里仅作为学习笔记

mycat基础配置

基础操作

mycat的配置总结 就是 通过schema配置数据库,而table则是配置需要连接的数据库, 其中table标签会指定dataNode中的name;dataNode则指向dataHost;最后由dataHost配置好连接的服务器,但是注意在table镖旗中的travelrecord需要留着,因为它的作用是来记录我们的操作的;

在102的服务中有存在着test的数据库其中就有一个t表;我们可以以它作为目标来接;

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
  <table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
  <!-- 配置连接对应的dataNode 数据源节点 -->
  <table name="t" dataNode="dn1" />
</schema>
<!-- 配置节点数据库名 -->
<dataNode name="dn1" dataHost="localhost1" database="test" />
<dataNode name="dn2" dataHost="localhost1" database="db2" />
<dataNode name="dn3" dataHost="localhost1" database="db3" />

<dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
  <heartbeat>select user()</heartbeat>
  <!-- 配置读写 的连接 数据库ip 地址 -->
  <writeHost host="hostM1" url="192.168.153.127:3306" user="root" password="root">
  <readHost host="hostS2" url="192.168.153.127:3306" user="root" password="root" />
</writeHost>
</dataHost>

然后重启mycat的服务,再尝试着连接mycat 来看一下效果

mysql> show databases;
+----------+
| DATABASE |
+----------+
| TESTDB |
+----------+
1 row in set (0.00 sec)
mysql> use TESTDB
Database changed
mysql> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| t |
| travelrecord |
+------------------+
2 rows in set (0.00 sec)
mysql> select * from t;
+----+------+
| id | name |
+----+------+
| 9 | 8 |
| 10 | 8 |
+----+------+
9 rows in set (0.13 sec)
mysql> insert into t values(11,1);
Query OK, 1 row affected (0.02 sec)
mysql> select * from t;
+----+------+
| id | name |
+----+------+
| 9 | 8 |
| 10 | 8 |
| 11 | 1 |
+----+------+
10 rows in set (0.01 sec)

然后再去102的服务器测试 发现也存在与数据;

尝试节点操作

比如我们以它配置的 company的信息来作操作演示,

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
  <table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
  <table name="t" dataNode="dn1" />
  <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
</schema>

重启mycat, 然后连接mycat操作

mysql> use TESTDB;
Database changed
mysql> show tables;
+------------------+
| Tables in TESTDB |
+------------------+
| company |
| t |
| travelrecord |
+------------------+
3 rows in set (0.01 sec)
mysql> select * from company;
ERROR 1184 (HY000):
mysql> create table company(id int primary key, name varchar(10));
ERROR 1105 (HY000): backend connect: ConnectionException [code=1049, msg=Unknown database 'db2']

ERROR 1105 (HY000): backend connect: ConnectionException [code=1049, msg=Unknown database ‘db2’] 这个错误主要是因为在102服务器中没有db2.db3的数据库产生的 ; 因此我们需要去创建这两个数据库,但是test是有的因此在102中的test数据库中是存在着创建成功的company表

当我们重新创建好了db2,db3之后就可以先在mycat删除原来创建表的操作;再执行创建就ok ,然后我们开去 102的MySQL服务器 中查看:

mysql> use db2; show tables;
Database changed
+---------------+
| Tables_in_db2 |
+---------------+
| company |
+---------------+
1 row in set (0.00 sec)
mysql> use db3; show tables;
Database changed
+---------------+
| Tables_in_db3 |
+---------------+
| company |
+---------------+
1 row in set (0.00 sec)
mysql> use test; show tables;
Database changed
+-----------------+
| Tables_in_test |
+-----------------+
| company |
| data_order |
| data_order_2018 |
| data_order_2019 |
| emp |
| heartbeat |
| sbtest1 |
| t |
| u |
+-----------------+
9 rows in set (0.00 sec)

解释:我们可以看到在每一个库中都会存在这个company这表,那也就是company的数据就来这三个库中。我们可以尝试给三个库添加一条数据看追加在那个数据库的表中;注意一定是要在 mycat的服务 中执行

mysql> explain insert into company values(1,2);
+-----------+---------------------------------+
| DATA_NODE | SQL |
+-----------+---------------------------------+
| dn1 | insert into company values(1,2) |
| dn2 | insert into company values(1,2) |
| dn3 | insert into company values(1,2) |
+-----------+---------------------------------+
3 rows in set (0.01 sec)

这是因为当前的company表设置是一个全局的,没有根据规则去分配;而是会选择所有的库都会去执行这样的操作,那么如果我们查询呢?会不会出现三条这样的数据?

mysql> use TESTDB;
Database changed
mysql> select * from company;
+----+------+
| id | name |
+----+------+
| 1 | 2 |
+----+------+
1 row in set (0.01 sec)

可以看到只有一条数据

mycat切分规则

我们可以先做个演示;以配置文件中的

<schema name="TESTDB" checkSQLschema="true" sqlMaxLimit="100">
  <table name="travelrecord" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
  <table name="t" dataNode="dn1" />
  <table name="company" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
  <table name="employee" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile" />
</schema>

重启mycat

mysql> CREATE TABLE `employee` (
`id` int(11) NOT NULL,
`name` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
mysql> select * from employee;
Empty set (0.08 sec)
mysql> desc employee;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(10) | YES | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into employee values (1, 'shineyork');
ERROR 1064 (HY000): partition table, insert must provide ColumnList

在执行的时候可以看到存在着这样的异常; 这个异常产生的原因主要是因为分区表需要有指定的字段去进行分区表没有指定分区的字段;也就是说当前的employee表实际上就是一个分区表,根据了某一个字段进行分区;而目前在当前的表中是没有这个字段产生的问题, 而这个分区的设置很显然是通过添加了rule=“sharding-by-intfile” 这个属性产生的;

rule属性的作用就是定义分区的规则 -》 而“sharding-by-intfile” 则是分区的规则, 那么这个分区定义在哪里?通过查看配置文件我们可以看导rule.xml;而这个配置文件则就是分片规则定义所在;

<tableRule name="sharding-by-intfile">
  <rule>
    <columns>sharding_id</columns>
    <algorithm>hash-int</algorithm>
  </rule>
</tableRule>

打开配置文件可以看到是存在这么一个信息的, 而tableRule就是定义一个规则, name属性就是规则名; rule标签就是规则内容,columns标签则就是规则的字段,而algorithm是规则方式

因此实际上我们需要在employee表中添加sharding_id这个字段,数据类型int

alter table employee add column sharding_id int not null;

在添加完了字段之后我们可以来试试添加数据

mysql> insert into employee values(1,'shineyork', 100);
ERROR 1064 (HY000): partition table, insert must provide ColumnList
mysql> insert into employee (id, name, sharding_id)values(1,'shineyork', 100);
ERROR 1064 (HY000): cant find any valid datanode :EMPLOYEE -> SHARDING_ID -> 100
mysql> insert into employee (id, name, sharding_id)values(1,'shineyork', 10000);
Query OK, 1 row affected (0.02 sec)
mysql> explain insert into employee (id, name, sharding_id)values(1,'shineyork', 10000);
+-----------+-------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------------------------------------------------+
| dn1 | INSERT INTO employee (id, name, sharding_id) VALUES (1, 'shineyork', '10000') |
+-----------+-------------------------------------------------------------------------------+
1 row in set (0.01 sec)
mysql> insert into employee (id, name, sharding_id)values(1,'shineyork', 10010);
Query OK, 1 row affected (0.01 sec)
mysql> explain insert into employee (id, name, sharding_id)values(1,'shineyork', 10010);
+-----------+-------------------------------------------------------------------------------+
| DATA_NODE | SQL |
+-----------+-------------------------------------------------------------------------------+
| dn2 | INSERT INTO employee (id, name, sharding_id) VALUES (1, 'shineyork', '10010') |
+-----------+-------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> explain insert into employee (id, name, sharding_id)values(1,'shineyork', 10020);
ERROR 1064 (HY000): cant find any valid datanode :EMPLOYEE -> SHARDING_ID -> 10020

如上操作演示之后我们可以看到employee在数据新增的时候根据sharding_id进行了数据的分区,而分区主要是根据value 10000与10010;并且字段列是必须要在insert 中指明的负责就无法实行;

对于数据进行查询

mycat查询

mysql> select * from employee;
+----+-----------+-------------+
| id | name | sharding_id |
+----+-----------+-------------+
| 1 | shineyork | 10000 |
| 1 | shineyork | 10010 |
+----+-----------+-------------+
2 rows in set (0.01 sec)

102中的MySQL 进行查询

mysql> use db2;select * from employee;
Database changed
+----+-----------+-------------+
| id | name | sharding_id |
+----+-----------+-------------+
| 1 | shineyork | 10010 |
+----+-----------+-------------+
1 row in set (0.01 sec)
mysql> use test;select * from employee;
Database changed
+----+-----------+-------------+
| id | name | sharding_id |
+----+-----------+-------------+
| 1 | shineyork | 10000 |
+----+-----------+-------------+
1 row in set (0.00 sec)

那么这个规则如何定义的呢?在rule.xml中有如下的配置信息

<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
  <property name="mapFile">partition-hash-int.txt</property>
</function>

其中制定了一个文件partition-hash-int.txt文件,我们可以看一下conf目录下的这个文件内容

10000=0
10010=1

可以看到有如上的配置;那么也就是说实际mycat的执行就是通过与根据sharding_id的值进行了if的判断选择了对应的数据源节点;我们可以看看源码;在github中下载好源码https://github.com/MyCATApache/Mycat-Server/releases

es,es-head,kibana简介与安装

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene。

Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它也仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中。 更糟糕的是,您可能需要获得信息检索学位才能了解其工作原理,因为Lucene 非常复杂。

为了解决Lucene使用时的繁复性,于是Elasticsearch便应运而生。它使用 Java 编写,内部采用 Lucene 做索引与搜索,但是它的目标是使全文检索变得更简单,简单来说,就是对Lucene 做了一层封装,它提供了一套简单一致的 RESTful API 来帮助我们实现存储和检索。

当然,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。 它可以被下面这样准确地形容:

一个分布式的实时文档存储,每个字段可以被索引与搜索;
一个分布式实时分析搜索引擎;
能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
由于Elasticsearch的功能强大和使用简单,维基百科、卫报、Stack Overflow、GitHub等都纷纷采用它来做搜索。现在,Elasticsearch已成为全文搜索领域的主流软件之一。

elasticsearch+elasticsearch-head+kibana环境安装

elasticsearch:分布式搜索引擎
elasticsearch-head:es搜索引擎可视化工具
kibana:针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示

Windows下安装

es分布式搜索引擎安装

安装要求:

jdk:最低要求是1.8 (jdk请从本节素材获取 或者 从www.java.com进行下载)

elasticsearch安装包下载地址:https://www.elastic.co/cn/downloads/elasticsearch
获取到安装包后,进行解压
目录结构介绍:

bin 启动文件
config 配置文件
> log4j2 日志配置文件
> jvm.options java 虚拟机相关的配置
> elasticsearch.yml elasticsearch 的配置文件! 默认 9200 端口! 跨域!
lib 相关jar包
logs 日志!
modules 功能模块
plugins 插件!

启动es
在这里插入图片描述
在这里插入图片描述
可以看到启动之后,程序给出了访问地址,在浏览器中访问:http://127.0.0.1:9200
在这里插入图片描述
得到elasticsearch相关的信息,说明安装成功!

elasticsearch-head安装

与elasticsearch一样得到安装包后直接进行解压,解压后得到目录如下:
在这里插入图片描述
在安装目录下打开cmd命令行,安装前端环境:

npm install --环境安装命令
npm run start --启动命令

在这里插入图片描述
运行完成上述命令即可。在到浏览器中访问head给出的访问地址:http://localhost:9100
在这里插入图片描述
得到可视化的elasticsearch界面。

kibana安装

Kibana 是为 Elasticsearch设计的开源分析和可视化平台。你可以使用 Kibana 来搜索,查看存储在 Elasticsearch 索引中的数据并与之交互。你可以很容易实现高级的数据分析和可视化,以图表的形式展现出来。
下面进行安装:

得到安装包后,进行解压,得到如下目录:

在这里插入图片描述

启动 kibana

在这里插入图片描述
在这里插入图片描述
访问程序给出的地址:http://localhost:5601
在这里插入图片描述
安装成功!

CentOS下安装

elasticsearch安装

  1. 解压elasticsearch-7.6.1-linux-x86_64.tar.gz到/usr/local/目录:

tar -xvf elasticsearch-7.6.1-linux-x86_64.tar.gz

  1. 进入解压后的elasticsearch目录:
    新建data

mkdir data

在这里插入图片描述
修改config/elasticsearch.yml:

vi config/elasticsearch.yml

取消或者修改下列项注释并修改:

cluster.name: my-application #集群名称
node.name: node-1 #节点名称
#数据和日志的存储目录
path.data: /usr/local/elasticsearch-7.6.1/data
path.logs: /usr/local/elasticsearch-7.6.1/logs
#设置绑定的ip,设置为0.0.0.0以后就可以让任何计算机节点访问到了
network.host: 0.0.0.0
http.port: 9200 #端口
#设置在集群中的所有节点名称,这个节点名称就是之前所修改的,当然你也可以采用默认的也行,目前 是单机,放入一个节点即可
cluster.initial_master_nodes: ["node-1"]

修改完毕后,:wq 保存退出vi

  1. 准备启动es
    进入/bin目录执行命令:

./elasticsearch 或者是 ./elasticsearch -d

这里出现如下错误:

Java HotSpot™ 64-Bit Server VM warning: INFO: os::commit_memory(0x00000000c5330000, 986513408, 0) failed; error=‘Cannot allocate memory’ (errno=12) ## There is insufficient memory for the Java Runtime Environment to continue. # Native memory allocation (mmap) failed to map 986513408 bytes for committing reserved memory. # An error report file with more information is saved as: # logs/hs_err_pid22863.log [root@localhost bin]#

elasticsearch使用java的jvm默认是使用1G的内存的,这里我们修改一下内存,直接把内存改到256m cd 到es 目录修改 ./config/jvm.options:

vi ./config/jvm.options

修改该内容:

-Xms256m
-Xmx256m

:wq 保存并退出vi,再次启动es

再次启动出现如下错误:

[2019-06-21T16:20:03,039][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [node-1] uncaught exception in thread [main] org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~ [elasticsearch-7.6.1.jar:7.1.1] at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~ [elasticsearch-7.6.1.jar:7.1.1] atorg.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-7.6.1.jar:7.1.1] at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~ [elasticsearch-cli-7.1.1.jar:7.1.1] at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli- 7.1.1.jar:7.1.1] at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:115) ~ [elasticsearch-7.6.1.jar:7.1.1]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~ [elasticsearch-7.6.1.jar:7.1.1] Caused by: java.lang.RuntimeException: can not run elasticsearch as root at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:102) ~ [elasticsearch-7.6.1.jar:7.1.1] at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:169) ~[elasticsearch- 7.6.1.jar:7.1.1] at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:325) ~[elasticsearch- 7.6.1.jar:7.1.1] at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159) ~ [elasticsearch-7.6.1.jar:7.1.1] ... 6 more
[root@localhost elasticsearch-7.6.1]#

这是不能使用root用户操作,添加一个其他的用户再试试:

[root@localhost elasticsearch-7.6.1]# useradd elasticsearch
[root@localhost elasticsearch-7.6.1]# passwd elasticsearch 更改用户 elasticsearch 的密码 。
新的 密码:
无效的密码: 密码少于 8 个字符
重新输入新的 密码:
passwd:所有的身份验证令牌已经成功更新。
[root@localhost elasticsearch-7.6.1]# chown -R elasticsearch /usr/local/elasticsearch- 7.6.1

vi 编辑 /etc/security/limits.conf,在末尾加上:

elasticsearch soft nofile 65536
elasticsearch hard nofile 65536
elasticsearch soft nproc 4096
elasticsearch hard nproc 4096

vi 编辑 vi /etc/security/limits.d/20-nproc.conf,将* 改为用户名(elasticsearch):

# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.

elasticsearch soft nproc 4096
root soft nproc unlimited

vi 编辑 /etc/sysctl.conf,在末尾加上:

vm.max_map_count = 655360

在root用户下执行:

[root@localhost ~]# sysctl -p
vm.max_map_count = 655360
[root@localhost ~]#

登录刚才新建的elasticsearch用户,并启动elasticsearch,OK

[root@localhost elasticsearch-7.6.1]# su es
[elasticsearch@localhost elasticsearch-7.6.1]$ ./bin/elasticsearch

在这里插入图片描述

elasticsearch-head安装

  1. 安装node.js
    wget https://nodejs.org/dist/v12.18.1/node-v12.18.1-linux-x64.tar.xz // 下载
    tar xf node-v12.18.1-linux-x64.tar.xz // 解压
    cd node-v12.18.1-linux-x64
    // 进入解压目录 解压文件的 bin 目录底下包含了 node、npm 等命令,我们可以修改linux系统的环境变量 (profile)来设置直接运行命令:
    export PATH=$PATH:/root/node-v12.18.1-linux-x64/bin
    source /etc/profile
    
  2. elasticsearch-head
1. 在/usr/local目录解压elasticsearch-head-master.zip
unzip elasticsearch-head-master.zip

2. 修改elasticsearch-head-master目录
mv elasticsearch-head-master elasticsearch-head

3. 在elasticsearch-head目录下安装
npm npm install //安装后面可能会出现异常,但是不会影响操作

4. 启动elasticsearch-head
npm run start

成功后会出现跨域问题,在elasticsearch.yml配置文件中配置跨域:

http.cors.enabled: true # elasticsearch中启用CORS
http.cors.allow-origin: "*" # 允许访问的IP地址段,* 为所有IP都可以访问

再次访问,OK:
在这里插入图片描述

kibana安装

1. 在/usr/local/解压kibana-7.6.1-linux-x86_64.tar.gz
tar -xvf kibana-7.6.1-linux-x86_64.tar.gz

2. 进入./kibana/bin目录启动
./kibana
Kibana should not be run as root. Use --allow-root to continue. 不能在root用户下启动

3. 创建kibana用户
useradd kibana
passwd kibana
chown -R kibana /usr/local/kibana

进入kibana用户启动kibana访问,OK:
在这里插入图片描述

es基础使用

elasticsearch入门

Relational DBElasticsearch
数据库(database)索引(indices)
表(tables)类型(types)
行(rows)文档(documents)
字段(columns)字段(fields)

elasticsearch(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又包含多个文档(行),每个文档中又包含多个字段(列)。

物理设计

elasticsearch 在后台把每个索引划分成多个分片,每分分片可以在集群中的不同服务器间迁移 一个人就是一个集群!默认的集群名称就是 elaticsearh
在这里插入图片描述

逻辑设计

一个索引类型中,包含多个文档,比如说文档1,文档2。 当我们索引一篇文档时,可以通过这样的一各 顺序找到 它: 索引 ▷ 类型 ▷ 文档ID ,通过这个组合我们就能索引到某个具体的文档。 注意:ID不必是整 数,实际上它是个字 符串。

文档
就是我们的一条条数据

user
1 zhangsan 18
2 kuangshen 3

之前说elasticsearch是面向文档的,那么就意味着索引和搜索数据的最小单位是文档,elasticsearch 中,文档有几个 重要属性 :

  • 自我包含,一篇文档同时包含字段和对应的值,也就是同时包含 key:value!
  • 可以是层次型的,一个文档中包含自文档,复杂的逻辑实体就是这么来的! {就是一个json对象! fastjson进行自动转换!}
  • 灵活的结构,文档不依赖预先定义的模式,我们知道关系型数据库中,要提前定义字段才能使用, 在elasticsearch中,对于字段是非常灵活的,有时候,我们可以忽略该字段,或者动态的添加一个 新的字段。

尽管我们可以随意的新增或者忽略某个字段,但是,每个字段的类型非常重要,比如一个年龄字段类 型,可以是字符 串也可以是整形。因为elasticsearch会保存字段和类型之间的映射及其他的设置。这种映射具体到每个映射的每种类型,这也是为什么在elasticsearch中,类型有时候也称为映射类型。

索引

就是数据库!

索引是映射类型的容器,elasticsearch中的索引是一个非常大的文档集合。索引存储了映射类型的字段 和其他设置。 然后它们被存储到了各个分片上了。 我们来研究下分片是如何工作的。

物理设计 :节点和分片 如何工作在这里插入图片描述
一个集群至少有一个节点,而一个节点就是一个elasricsearch进程,节点可以有多个索引默认的,如果 你创建索引,那么索引将会有个5个分片 ( primary shard ,又称主分片 ) 构成的,每一个主分片会有一个 副本 ( replica shard ,又称复制分片 )
在这里插入图片描述
上图是一个有3个节点的集群,可以看到主分片和对应的复制分片都不会在同一个节点内,这样有利于某 个节点挂掉 了,数据也不至于丢失。 实际上,一个分片是一个Lucene索引,一个包含倒排索引的文件 目录,倒排索引的结构使 得elasticsearch在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的 关键字。 不过,等等,倒排索引是什 么鬼?

倒排索引

elasticsearch使用的是一种称为倒排索引的结构,采用Lucene倒排索作为底层。这种结构适用于快速的全文搜索, 一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。 例如,现在有两个文档, 每个文档包含如下内容:

Study every day, good good up to forever # 文档1包含的内容
To forever, study every day, good good up # 文档2包含的内容

为了创建倒排索引,我们首先要将每个文档拆分成独立的词(或称为词条或者tokens),然后创建一个包 含所有不重 复的词条的排序列表,然后列出每个词条出现在哪个文档 :

termdoc_1doc_2
Studyx
Tox×
every
forever
day
study×
good
every
to×
up

现在,我们试图搜索 to forever,只需要查看包含每个词条的文档

termdoc_1doc_2
to×
forever
total21

两个文档都匹配,但是第一个文档比第二个匹配程度更高。如果没有别的条件,现在,这两个包含关键 字的文档都将返回。

再来看一个示例,比如我们通过博客标签来搜索博客文章。那么倒排索引列表就是这样的一个结构 :

在这里插入图片描述
如果要搜索含有 python 标签的文章,那相对于查找所有原始数据而言,查找倒排索引后的数据将会快 的多。只需要 查看标签这一栏,然后获取相关的文章ID即可。完全过滤掉无关的所有数据,提高效率!

elasticsearch的索引和Lucene的索引对比

在elasticsearch中, 索引 (库)这个词被频繁使用,这就是术语的使用。 在elasticsearch中,索引被 分为多个分片,每份 分片是一个Lucene的索引。所以一个elasticsearch索引是由多个Lucene索引组成 的。别问为什么,谁让elasticsearch使用Lucene作为底层呢! 如无特指,说起索引都是指elasticsearch 的索引。

接下来的一切操作都在kibana中Dev Tools下的Console里完成。基础操作!

elasticsearch简单查询

ik分词器安装 声明:安装完成后需要重新启动elasticsearch,elasticsearch-head,kibana 1. 在elasticsearch目录的plugins解压elasticsearch-analysis-ik-7.6.1.zip

unzip elasticsearch-analysis-ik-7.6.1.zip

ik分词器介绍

分词:即把一段中文或者别的划分成一个个的关键字,我们在搜索时候会把自己的信息进行分词,会把数据库中或者索引库中的数据进行分词,然后进行一个匹配操作,默认的中文分词是将每个字看成一个词,比如:

“中国的花"会被分为"中”,“国”,“的”,“花”,这显然是不符合要求的,所以我们需要安装中文分词器ik来解决这个问题

如果要使用中文,建议使用ik分词器!

IK提供了两个分词算法:ik_smart 和 ik_max_word,其中 ik_smart 为最少切分,ik_max_word为最细 粒度划分!一会我们测试!

  1. elasticsearch-plugin 可以通过这个命令来查看加载进来的插件
    在这里插入图片描述

ik_smart为最少切分

在这里插入图片描述

ik_max_word为最细粒度划分!穷尽词库的可能!字典!

在这里插入图片描述
发现问题:好帅被拆开了!

这种自己需要的词,需要自己加到我们的分词器的字典中!

ik 分词器增加自己的配置!

在这里插入图片描述
再次查看分词效果
在这里插入图片描述
以后的话,我们需要自己配置 分词就在自己定义的dic文件中进行配置即可!

elasticsearch基本操作

一种软件架构风格,而不是标准,只是提供了一组设计原则和约束条件。它主要用于客户端和服务器交 互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。

基本Rest命令说明:

methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
POSTlocalhost:9200/索引名称/类型名称创建文档(随机文档id)
POSTlocalhost:9200/索引名称/类型名称/文档id/_update修改文档
DELETElocalhost:9200/索引名称/类型名称/文档id删除文档
GETlocalhost:9200/索引名称/类型名称/文档id查询文档通过文档id
POSTlocalhost:9200/索引名称/类型名称/_search查询所有数据

关于索引的基本操作

  1. 创建一个索引!

PUT /索引名/类型名/文档id
{请求体}
在这里插入图片描述
完成了自动增加了索引!数据也成功的添加了,这就是我说大家在初期可以把它当做数据库学习的原因!

在这里插入图片描述
2. 那么 name 这个字段用不用指定类型呢。毕竟我们关系型数据库 是需要指定类型的啊 !

  • 字符串类型 text 、 keyword

  • 数值类型 long, integer, short, byte, double, float, half_float, scaled_float

  • 日期类型 date PUT /索引名/类型名/文档id {请求体}

  • te布尔值类型 boolean

  • 二进制类型 binary

  • 等等

  • 指定字段的类型

在这里插入图片描述
获得这个规则! 可以通过 GET 请求获取具体的信息!
在这里插入图片描述

扩展: 通过命令 elasticsearch 索引情况! 通过get _cat/ 可以获得es的当前的很多信息!

在这里插入图片描述

修改 提交还是使用PUT 即可! 然后覆盖!最新办法!

曾经!
在这里插入图片描述
现在的方法!
在这里插入图片描述

删除索引!

通过DELETE 命令实现删除、 根据你的请求来判断是删除索引还是删除文档记录!

使用RESTFUL 风格是我们ES推荐大家使用的!

laravel使用elasticsearch

引入 Composer 包

Elasticsearch 官方提供了 Composer 包,在引入时需要注意要指定版本,因为不同版本的 Elasticsearch 的 API 略有不同,我们用的是 7.x,因此需使用 ~7.0 来指定包版本。

$ composer require elasticsearch/elasticsearch ‘~7.0’

为什么不用 Scout?
熟悉 Laravel 的同学,应该会有此疑问。Scout 是 Laravel 官方出的一个让 Eloquent 模型支持全文搜索的包,这个包封装好一批方法,通过这些方法就可以将数据索引到全文搜索引擎中、以及使用关键字从搜索引擎搜索文档。这个包适用于一些简单的搜索场景,比如博客文章搜索,但无法发挥出全文搜索引擎全部威力,像 Elasticsearch 这种重量级的搜索引擎有无数种查询语句,例如 我们将会学到的 should 语句、模糊查询、分片查询等,根本不是 Scout 几个简单的方法能够覆盖的,也就无法满足电商系统搜索模块的需求。

配置

Elasticsearch 的配置很简单,我们只需要 Elasticsearch 服务器的 IP 和端口即可:

config/database.php

<?php
.
.
.
    'elasticsearch' => [
        // Elasticsearch 支持多台服务器负载均衡,因此这里是一个数组
        'hosts' => explode(',', env('ES_HOSTS')),
    ]
?>

我们本地环境的 Elasticsearch 的 IP 和端口是 localhost:9200,如果端口是 9200 则可以忽略不写:
.env

.
.
.
ES_HOSTS=localhost

初始化ELasticsearch对象

接下来我们将初始化 Elasticsearch 对象,并注入到 Laravel 容器中:

app/Providers/AppServiceProvider.php

<?php
use Elasticsearch\ClientBuilder as ESClientBuilder;
.
.
.
    public function register()
    {
        .
        .
        .
        // 注册一个名为 es 的单例
        $this->app->singleton('es', function () {
            // 从配置文件读取 Elasticsearch 服务器列表
            $builder = ESClientBuilder::create()->setHosts(config('database.elasticsearch.hosts'));
            // 如果是开发环境
            if (app()->environment() === 'local') {
                // 配置日志,Elasticsearch 的请求和返回数据将打印到日志文件中,方便我们调试
                $builder->setLogger(app('log')->driver());
            }

            return $builder->build();
        });
    }
.
.
.
?>

测试

接下来我们来测试一下能否正常工作,首先进入 tinker:

$ php artisan tinker

然后输入:

>>>app(‘es’)->info()

在这里插入图片描述
可以看到返回正常,接下来我们看看日志里有没有对应的请求和响应:shift+g 跳至末尾
在这里插入图片描述
可以看到有记录下请求和返回。

接下来我们试试用 PHP 来读取之前创建的 Elasticsearch 文档:

>>> app(‘es’)->get([‘index’ => ‘test_index’, ‘id’ => 1])

get() 方法用于读取文档,index 代表要读取的索引名称,id 则是指定要读取的文档 ID。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值