Redis和elasticsearch
redis
-----------NOSQL的对比和劣和应用场景参考好文 http://www.redis.cn/articles/20181020003.html ---------
-----------REDIS架构好文章 https://www.cnblogs.com/mrhelloworld/p/redis-architecture.html----------------
简介
redis是一款高性能的NOSQL系列的非关系型数据库
支持的类型
1) 字符串类型 string
2) 哈希类型 hash
3) 列表类型 list
4) 集合类型 set
5) 有序集合类型 sortedset
应用场景
• 缓存(数据查询、短连接、新闻内容、商品内容等等)
• 聊天室的在线好友列表
• 任务队列。(秒杀、抢购、12306等等)
• 应用排行榜
• 网站访问统计
• 数据过期处理(可以精确到毫秒
• 分布式集群架构中的session分离
持久化
redis持久化机制:
1. RDB:默认方式,不需要进行配置,默认就使用这种机制
* 在一定的间隔时间中,检测key的变化情况,然后持久化数据
1. 1编辑redis.windwos.conf文件
# 900秒(15分钟)后,如果至少有一个键被改变持久化一次
save 900 1
# after 300 sec (5 min) if at least 10 keys changed
save 300 10
# after 60 sec if at least 10000 keys changed
save 60 10000
2. AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
1. 1编辑redis.windwos.conf文件
appendonly no(关闭aof) --> appendonly yes (开启aof)
# appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
# appendfsync no : 不进行持久化
缓存穿透、缓存击穿、缓存雪崩
缓存穿透
缓存穿透是指缓存和数据库中都没有的数据,而用户不
断发起请求,如发起为id 为“-1”的数据或id为特别大
不存在的数据。这时的用户很可能是攻击者,攻击会导
致数据 库压力过大。
解决方案:
1.接口层增加校验,如用户鉴权校验,id做基础校验,|id<=0的直接拦截;
2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为 key-0。这样可以防止攻击用户反复用同一个id暴力攻击
3. 使用缓存预热缓存预热就是将数据提前加入到缓存
中,当数据发生变更,再将最新的数据更新到缓 存
缓存击穿
缓存击穿是指缓存中没有但数据库中有的数据。这时由
于并发用户特别多,同时读 缓存没读到数据,又同时
去数据库去取数据,引起数据库压力瞬间增大,造成过
大压 力。
解决方案:
1.设置热点数据永远不过期。
2.缓存预热
缓存雪崩
缓存雪崩是指缓存数据大批量到过期时间,而查询数
据量巨大,引起数据库压力过 大甚至down机。和缓存
击穿不同的是,缓存击穿指并发查同一条数据,缓存雪
崩是不同 数据都过期了,很多数据都查不到从而查数
据库。
解决方案:
1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。 2.设置热点数据永远不过期。
3.使用缓存预热
MQ
消息中间件简介
消息中间件(消息队列)是分布式系统中重要的组件,
主要解决应用耦合,异步消 息,流量削锋等问题实现
高性能,高可用,可伸缩和最终一致性[架构] 使用较
多的消息 队列有ActiveMQ,RabbitMQ,ZeroMQ,
Kafka,MetaMQ,RocketMQ
以下介绍消息队列在实际应用中常用的使用场景:异步
处理,应用解耦,流量削锋和消 息通讯四个场景
MQ简介
AMQP :Advanced Message Queue,高级消息队列
协议。它是应用层协议的一个开放 标准,为面向消息
的中间件设计,基于此协议的客户端与消息中间件可传
递消息,并不 受产品、开发语言等条件的限制
主要概念 :
RabbitMQ Server: 也叫broker server,它是一种传输服务。 他的角色就是维护一条 从Producer到Consumer的路线,保证数据能够按照指定的方式进行传输。
Producer: 消息生产者,如图A、B、C,数据的发送方。消息生产者连接RabbitMQ服 务器然后将消息投递到Exchange。
Consumer:消息消费者,如图1、2、3,数据的接收方。消息消费者订阅队列, RabbitMQ将Queue中的消息发送到消息消费者。 Exchange:生产者将消息发送到Exchange(交换器),由Exchange将消息路由到一个 或多个Queue中(或者丢弃)。Exchange并不存储消息。RabbitMQ中的Exchange有 direct、fanout、topic、headers四种类型,每种类型对应不同的路由规则。
Queue:(队列)是RabbitMQ的内部对象,用于存储消息。消息消费者就是通过订阅 队列来获取消息的,RabbitMQ中的消息都只能存储在Queue中,生产者生产消息并最终 投递到Queue中,消费者可以从Queue中获取消息并消费。多个消费者可以订阅同一个 Queue,这时Queue中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者 都收到所有的消息并处理。
RoutingKey:生产者在将消息发送给Exchange的时候,一般会指定一个routing key, 来指定这个消息的路由规则,而这个routing key需要与Exchange Type及binding key联 合使用才能最终生效。在Exchange Type与binding key固定的情况下(在正常使用时一 般这些内容都是固定配置好的),我们的生产者就可以在发送消息给Exchange时,通过 指定routing key来决定消息流向哪里。RabbitMQ为routing key设定的长度限制为255 bytes。
Connection: (连接):Producer和Consumer都是通过TCP连接到RabbitMQ Server 的。以后我们可以看到,程序的起始处就是建立这个TCP连接。
Channels: (信道):它建立在上述的TCP连接中。数据流动都是在Channel中进行 的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。
VirtualHost:权限控制的基本单位,一个VirtualHost里面有若干Exchange和 MessageQueue,以及指定被哪些user使用
RabbitMQ发送与接收消息
直接模式(Direct)
我们需要将消息发给唯一一个节点时使用这种模式,这是最简单的一种形式。
任何发送到Direct Exchange的消息都会被转发到RouteKey中指定的Queue。
1.一般情况可以使用rabbitMQ自带的Exchange:”"(该Exchange的名字为空字符串,下 文称其为default Exchange)。
2.这种模式下可以不需要将Exchange进行任何绑定(binding)操作
3.消息传递时需要一个“RouteKey”,可以简单的理解为要发送到的队列名字。
4.如果vhost中不存在RouteKey中指定的队列名,则该消息会被抛弃。
分裂模式
当我们需要将消息一次发给多个队列时,需要使用这种模式
任何发送到Fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有 Queue上。
1.这种模式需要提前将Exchange与Queue进行绑定,一个Exchange可以绑定多个 Queue,一个Queue可以同多个Exchange进行绑定。
2.这种模式不需要RouteKey(其实就是队列名字)
3.如果接受到消息的Exchange没有与任何Queue绑定,则消息会被抛弃。
搜索技术Elasticsearch
简介
ElasticSearch是一个基于Lucene的搜索服务器。它提
供了一个分布式多用户能力的 全文搜索引擎,基于RES
Tful web接口。Elasticsearch是用Java开发的,并作
为Apache 许可条款下的开放源码发布,是当前流行的
企业级搜索引擎。设计用于云计算中,能够 达到实时
搜索,稳定,可靠,快速,安装使用方便。
IK分词是一款国人开发的相对简单的中文分词器。虽然
开发者自2012年之后就不在维护 了,但在工程应用中I
K算是比较流行的一款
创建索引与映射字段
类型名称:就是前面将的type的概念,类似
于数据库中的不同表 字段名:任意填写 ,可以指定许多属性,例如:
type:类型,可以是text、long、short、date、integer、object等
index:是否索引,默认为true
store:是否单独存储,默认为false ,一般内容比较多的字段设置成true,可提 升查询性能
analyzer:分词器
创建索引 和 映射
// 请求方式 /索引名称
PUT /.....
//创建索引--------------------------------
{
// 索引设置,并设置主分片和副本分片个数
"settings": {
"index": {
"number_of_shards": "16",
"number_of_replicas": "0"
}
},
//put localhost:9200/...
//创建 映射,--------------------------------
"mappings": {
"article": { //映射类型(自己定义)
"properties": {
"id": { //文章的编号
"type": "long", //相当于数据的字段类型
"store": true, .//是否存储
"index":"not_analyzed" //
},
"title": {//文章的题目
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
},
"content":{ //文章内容
"type": "text",
"store": true,
"index":"analyzed",
"analyzer":"standard"
}
}
}
}
}
创建文档document 向映射添加数据
POST localhost:9200/....
{
"id":1,
"title":"ElasticSearch是一个基于Lucene的搜索服务器",
"content":"它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java 开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时 搜索,稳定,可靠,快速,安装使用方便。"
}
索引删除
DELETE localhost:9200/索引名字
删除document
DELETE localhost:9200/索引名字/索引类型/document的id
查询文档-querystring查询
POST localhost:9200/索引名/类型/_search
//根据文章的标题 搜索"搜索服务器"的关键字 {
"query": { "query_string": { "default_field": "title", //document的某个属性(此处是按照文章的标题搜索,也可以是文章的内容content
"query": "搜索服务器" //搜索的关键字
}
}
}
使用IK 分词器
在创建索引映射的时候进行设置
IK提供了两个分词算法
ik_smart 和 ik_max_word 其中 ik_smart 为最少切分,
ik_max_word为最细粒度划分
"analyzer":"ik_max_word" //设置
过滤查询(java代码方式)
//1.封装查询请求...................................................................................................
SearchRequest searchRequest=new SearchRequest("sku1");
searchRequest.types("doc"); //设置查询的类型
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//布尔查询构建器
//1.1关键字搜索
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", searchMap.get("keywords"));
boolQueryBuilder.must(matchQueryBuilder);
高亮
GET /sku/doc/_search {"query":{ "match":{ "name":"手机"} }, "highlight":{ "fields":{ "name":{ "pre_tags":"<font style='color:red'>", "post_tags":"</font>" } } }, "size":2 }