linux安装es-head

1安装npm

curl --silent --location https://rpm.nodesource.com/setup_10.x | bash -
yum install -y nodejs
npm install -g cnpm --registry=https://registry.npm.taobao.org
npm install
npm run build
npm -v

2 安装head插件

wget https://github.com/mobz/elasticsearch-head/archive/master.zip
unzip master.zip
cd elasticsearch-head-master
npm install –g grunt–cli

权限

chown -R root:root /home/app/elasticsearch/elasticsearch-head-master/

安装

npm install

head安装完成后,将es后台启动、head也运行起来

./elasticsearch-5.5.1/bin/elasticsearch -d 
/home/app/elasticsearch/elasticsearch-head-master下:npm run start

需要后台启动执行
#nohup npm run start &

因为es是端口9200,而head插件是9100,,解决跨域问题:

elasticsearch-5x下的 config/elasticsearch.yml
http.cors.enabled: true
http.cors.allow-origin: "*"

linux安装es

1.解压 tar -zxvf elasticsearch-7.7.1-linux-x86_64.tar.gz
移动  mv elasticsearch-7.7.1 /usr/local/
cd /usr/local/
创建新用户  useradd esuser
赋权 chown -R esuser:esuser /usr/local/elasticsearch-7.7.1/

主配置文件修改 vim elasticsearch.yml

node.name: node-1
cluster.initial_master_nodes: ["node-1"]

network.host: 0.0.0.0

 

查看端口 netstat -tunlp|grep 9200

开启

su esuser
cd /usr/local/elasticsearch-7.7.1/bin/

./elasticsearch -d
问题:

vim /etc/security/limits.conf //保存后需要重新登录

* soft nofile 65536
* hard nofile 131072
* soft nproc 4096
* hard nproc 4096

976 vim /etc/sysctl.conf

vm.max_map_count=262145

sysctl -p//保存后刷新配置


redis安装和常用操作

安装&启动
一.下载:[root@localhost ]# wget http://download.redis.io/releases/redis-5.0.7.tar.gz
二.解压:[root@localhost ]# tar -xzvf redis-5.0.7.tar.gz
三.[root@localhost redis-5.0.7]# yum install gcc
四.[root@localhost ]# cd redis-5.0.7/
五.[root@localhost redis-5.0.7]# make MALLOC=libc
六.[root@localhost redis-5.0.7]# make install PREFIX=/usr/redis
七.启动进入 bin 目录 #./redis-server    客户端连接 #./redis-cli

继续阅读“redis安装和常用操作”

MyISAM与InnoDB 的区别

区别:

1. InnoDB支持事务,MyISAM不支持,对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;

2. InnoDB支持外键,而MyISAM不支持。对一个包含外键的InnoDB表转为MYISAM会失败;

3. InnoDB是聚集索引,使用B+Tree作为索引结构,数据文件是和(主键)索引绑在一起的(表数据文件本身就是按B+Tree组织的一个索引结构),必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。

MyISAM是非聚集索引,也是使用B+Tree作为索引结构,索引和数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

也就是说:InnoDB的B+树主键索引的叶子节点就是数据文件,辅助索引的叶子节点是主键的值;而MyISAM的B+树主键索引和辅助索引的叶子节点都是数据文件的地址指针。

 

4. InnoDB不保存表的具体行数,执行select count(*) from table时需要全表扫描。而MyISAM用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快(注意不能加有任何WHERE条件);

那么为什么InnoDB没有了这个变量呢?

因为InnoDB的事务特性,在同一时刻表中的行数对于不同的事务而言是不一样的,因此count统计会计算对于当前事务而言可以统计到的行数,而不是将总行数储存起来方便快速查询。InnoDB会尝试遍历一个尽可能小的索引除非优化器提示使用别的索引。如果二级索引不存在,InnoDB还会尝试去遍历其他聚簇索引。
如果索引并没有完全处于InnoDB维护的缓冲区(Buffer Pool)中,count操作会比较费时。可以建立一个记录总行数的表并让你的程序在INSERT/DELETE时更新对应的数据。和上面提到的问题一样,如果此时存在多个事务的话这种方案也不太好用。如果得到大致的行数值已经足够满足需求可以尝试SHOW TABLE STATUS
5. Innodb不支持全文索引,而MyISAM支持全文索引,在涉及全文索引领域的查询效率上MyISAM速度更快高;PS:5.7以后的InnoDB支持全文索引了

6. MyISAM表格可以被压缩后进行查询操作

7. InnoDB支持表、行(默认)级锁,而MyISAM支持表级锁

InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。潜台词是,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。不论是使用主键索引、唯一索引或普通索引,InnoDB都会使用行锁来对数据加锁

锁的粒度不同。MyISAM仅支持表锁。每次操作锁住整张表。这种处理方式一方面加锁的开销比较小,且不会出现死锁,但另一方面并发性能较差。InnoDB支持行锁。每次操作锁住一行数据,一方面行级锁在每次获取锁和释放锁的操作需要消耗比表锁更多的资源,速度较慢,且可能发生死锁,但是另一方面由于锁的粒度较小,发生锁冲突的概率也比较低,并发性较好。此外,即使是使用了InnoDB存储引擎,但如果MySQL执行一条sql语句时不能确定要扫描的范围,也会锁住整张表

MyISAM: 只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。

InnoDB: 支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表(没用索引)。

8、InnoDB表必须有主键(用户没有指定的话会自己找或生产一个主键),而Myisam可以没有

9、Innodb存储文件有frm、ibd,而Myisam是frm、MYD、MYI

Innodb:frm是表定义文件,ibd是数据文件

Myisam:frm是表定义文件,myd是数据文件,myi是索引文件

10. 缓存机制不同。MyISAM仅缓存索引信息,而不缓存实际的数据信息。而InnoDB不仅缓存索引信息,还会缓存数据信息。其将数据文件按页读取到缓冲池,然后按最近最少使用的算法来更新数据

 

如何选择:

1. 是否要支持事务,如果要请选择innodb,如果不需要可以考虑MyISAM;

2. 如果表中绝大多数都只是读查询,可以考虑MyISAM,如果既有读也有写,请使用InnoDB。

3. 系统奔溃后,MyISAM恢复起来更困难,能否接受;

4. MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的,如果你不知道用什么,那就用InnoDB,至少不会差。

 

InnoDB为什么推荐使用自增ID作为主键?

答:自增ID可以保证每次插入时B+索引是从右边扩展的,可以避免B+树和频繁合并和分裂(对比使用UUID)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。

 

innodb引擎的4大特性

插入缓冲(insert buffer),二次写(double write),自适应哈希索引(ahi),预读(read ahead)

版权声明:本文为CSDN博主「Chackca」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_35642036/java/article/details/82820178

设置session cookie_lifetime 使浏览器关闭后还能继续保持登录状态

php.ini

session.cookie.lifetime

设置cookie_lifetime为0但一关闭浏览器后session就被删除无法保持登录状态

如果设置cookie_lifetime为7200,则表示存活2个小时,此时就算关闭浏览器也不会删除session,再次打开浏览器依然保持登录状态

session.gc.maxlifetime

session.gc.maxlifetime是指设置session最大的过期时间,指php按照一定的几率 执行它的垃圾回收机制,

这个机制指判断当前时间减去session文件最后修改时间是否大于session.gc.maxlifetime,是则删除session文件;

但session.save_path分级的话就不会执行这个回收机制;

单点登录

技术实现的机制

当用户第一次访问应用系统的时候,因为还没有登录,会被引导到认证系统中进行登录;根据用户提供的登录信息,认证系统进行身份校验,如果通过校验,应该返回给用户一个认证的凭据--ticket;用户再访问别的应用的时候,就会将这个ticket带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行校验,检查ticket的合法性。如果通过校验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。

要实现SSO,需要以下主要的功能:

所有应用系统共享一个身份认证系统。

  • 统一的认证系统是SSO的前提之一。认证系统的主要功能是将用户的登录信息和用户信息库相比较,对用户进行登录认证;认证成功后,认证系统应该生成统一的认证标志(ticket),返还给用户。另外,认证系统还应该对ticket进行效验,判断其有效性。所有应用系统能够识别和提取ticket信息
  • 要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。

使用similar_text函数,实现相似标题文章推荐

$title1 = "特朗普发了一句话 遭美网友模仿造句怒怼";
$title2 = array(
    "特朗普",
    "特朗普发了一句话怒怼",
    " 遭美网友模仿造句怒怼",
    "了一句话 遭美网友模仿造句怒怼",
    "特朗普发了一句话 遭美网友模仿"
);


class a
{
    public function getSimilar($title, $arr_title)
    {
        $arr_len = count($arr_title);
        for ($i = 0; $i <= ($arr_len - 1); $i++) {
            //获取两个字符串相似的字节数
            $arr_similar[$i] = similar_text($arr_title[$i], $title, $persent);
        }
        arsort($arr_similar); //按照相似的字节数由高到低排序
        reset($arr_similar); //将指针移到数组的第一单元
        $index = 0;
        foreach ($arr_similar as $old_index => $similar) {
            $new_title_array[$index] = $arr_title[$old_index];
            $index++;
        }
        return $new_title_array;

    }
}
$obj = new a();
$res = $obj->getSimilar($title1,$title2);
var_dump($res);die;

继续阅读“使用similar_text函数,实现相似标题文章推荐”

redis缓存穿透,缓存击穿,缓存雪崩

缓存穿透定义:

key对应的数据在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

原因:

1、恶意攻击,猜测你的key命名方式,然后估计使用一个你缓存中不会有的key进行访问。

2、第一次数据访问,这时缓存中还没有数据,则并发场景下,所有的请求都会压到数据库。

3、数据库的数据也是空,这样即使访问了数据库,也是获取不到数据,那么缓存中肯定也没有对应的数据。这样也会导致穿透。

解决:

1,布隆过滤器 或 规范key的命名,对key的规范进行检测。

2,缓存空对象,同时会设置一个过期时间,注意:为了节省空间,需要定期清理空值

存在问题:1)如果空值能够被缓存起来,这就意味着缓存需要更多的空间存储更多的键,因为这当中可能会有很多的空值的键;2)即使对空值设置了过期时间,还是会存在缓存层和存储层的数据会有一段时间窗口的不一致,这对于需要保持一致性的业务会有影响。

3,常用数据提前写入缓存

缓存击穿:

key对应的数据存在,但在redis中过期,此时若有大量并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

解决办法:

1.使用互斥锁(mutex key)

public String get(key) {
    String value = redis.get(key);
    if (value == null) { //代表缓存值过期
        //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db
        String keynx = key.concat(":nx");
        if (redis.setnx(keynx, 1, 3 * 60) == 1) { //代表设置成功
            value = db.get(key);
            redis.set(key, value, expire_secs);
            redis.del(keynx);
        } else {
            //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可
            sleep(50);
            get(key); //重试
        }
    } else {
        return value;        
    }
}

继续阅读“redis缓存穿透,缓存击穿,缓存雪崩”

[ES]模糊搜索match_phrase和wildcard的比较

代码示例
<?php
$params = [
    'index' => 'mysql_table_test',
    'type' => 'out',
    'body' => [
        'query' => [
            'bool' => [
                'should' => [
                   [ 'wildcard' => [ 'name' => 'e*'] ],
                ]
            ]
        ],
        'from'=>0,
        'size'=>5,
        'highlight' => [
            'pre_tags' => "<h1 style='color:red'>",
            'post_tags' => "</h1>",
            'fields' => [
                "name" => new \stdClass()
            ]
        ]
    ]
];

$results = $client->search($params);

match_phrase

句子中包含helloworld的都会被搜索出:

 

GET /my_index/address/_search
{
    query: {match:"hello world"}
}

句子中包含hello world的会被搜索出:

 

GET /my_index/address/_search
{
    query: {match_phrase:"hello world"}
}

也就是说hello world 必须相邻。

再看一个例子:

 

GET /my_index/address/_search
{
    query: {match_phrase:{content:"hello world", slop: 2}}
}

这个搜索hello es world也会被搜索出来,因为中间间隔的词数为1 < 2。可以通过指定slot来控制移动词数。

执行过程:
match_phrase执行过程:
1.如match搜索一样进行分词,
2.对分词后的单词到field中去进行搜索(多个term匹配)。这一步返回每个单词对应的doc,并返回这些单词在对应的doc中的位置,
3.对返回的doc进行第一步的筛选,找到每个单词都在同一个field的doc。
4.对第3步进行筛选后的doc进行再一次的筛选,选回位置符合要求的doc。比如,对于match_phrase,就是找到后一个单词的位置比前一个单词的位置大1。或者移动次数<slot的文档。
5.proximity match(使用slot)原理一样,只是第四位对位置进行筛选时的方法不同。

比如要搜索“hello world”

  1. 分词为 hello 和 world
  2. 分别对term hello和world去搜索。返回两者匹配到的文档。
  3. 第一次筛选,取两个的交集。
  4. 继续筛选,对于match_phrase,就是找到后一个单词world的位置比前一个单词hello的位置大1的文档

prefix

  • 在搜索之前它不会分析查询字符串,它认为传入的前缀就是想要查找的前缀
  • 默认状态下,前缀查询不做相关度分数计算,它只是将所有匹配的文档返回,然后赋予所有相关分数值为1。它的行为更像是一个过滤器而不是查询。两者实际的区别就是过滤器是可以被缓存的,而前缀查询不行。
  • 只能找到反向索引中存在的术语

prefix的原理:
需要遍历所有倒排索引,并比较每个term是否已所指定的前缀开头。
比如,

 

Term:          Doc IDs:
-------------------------
"SW5 0BE"    |  5
"W1F 7HW"    |  3
"W1V 3DG"    |  1
"W2F 8HW"    |  2
"WC1N 1LZ"   |  4
-------------------------

GET /my_index/address/_search
{
    "query": {
        "prefix": {
            "postcode": "W1"
        }
    }
}

搜索过程:
为了支持前缀匹配,查询会做以下事情:

  1. 扫描术语列表并查找到第一个以 W1 开始的术语。
  2. 搜集关联的ID
  3. 移动到下一个术语
  4. 如果这个术语也是以 W1 开头,查询跳回到第二步再重复执行,直到下一个术语不以 W1 为止。

如果以w1开头的term很多,那么会有严重的性能问题。但是如果term比较小集合,可以放心使用。

wildcard

  • 工作原理和prefix相同,只不过它在1不是只比较开头,它能支持更为复杂的匹配模式。
  • 它使用标准的 shell 模糊查询:? 匹配任意字符,* 匹配0个或多个字符。

 

GET /my_index/address/_search
{
    "query": {
        "regexp": {
            "postcode": "W[0-9].+" #1
        }
    }
}

这也意味着我们需要注意与前缀查询中相同的性能问题,执行这些查询可能会消耗非常多的资源,所以我们需要避免使用左模糊这样的模式匹配(如,foo 或 .foo 这样的正则式)

注意:
prefix、wildcard 和 regrep 查询是基于术语操作的,如果我们用它们来查询分析过的字段(analyzed field),他们会检查字段里面的每个术语,而不是将字段作为整体进行处理。

match_phrase_prefix

这种查询的行为与 match_phrase 查询一致,不同的是它将查询字符串的最后一个词作为前缀使用。
比如:

 

{
    "match_phrase_prefix" : {
        "brand" : "johnnie walker bl"
    }
} 
  • johnnie
  • 跟着 walker
  • 跟着 一个以 bl 开始的词(prefix)

与 match_phrase 一样,它也可以接受 slop 参数让相对词序位置不那么严格:

 

{
    "match_phrase_prefix" : {
        "brand" : {
            "query": "walker johnnie bl", #1
            "slop":  10
        }
    }
}

我们可以通过设置 max_expansions 参数来限制前缀扩展的影响,一个合理的值是可能是50:

 

{
    "match_phrase_prefix" : {
        "brand" : {
            "query":          "johnnie walker bl",
            "max_expansions": 50
        }
    }
}

参数max_expansions控制着可以与前缀匹配的术语的数量

另一个即时搜索的方法是,使用 Ngram部分匹配, 这种方法会增加索引的开销,但是会加快查询速度。具体可以自行查阅

作者:ten5743
链接:https://www.jianshu.com/p/fb2761cd569b