2021-02-14 情人节关于ES的思考

ES,ElasticSearch的缩写,并不特殊,特殊的是今天是西方的情人节,说起情人节,是不是最先想到的是圣瓦伦丁这位大神,一个基督徒。其实这位大哥跟情人节没什么直接关系,把情人节跟他的名字联系在一起的是英国的李白,乔叟;把情人节炒作起来的是贺卡/邮币商人还有当初做了心形巧克力的吉百利。
ES跟数据库有些相似之处,毕竟它也来自Compass,15年前为西安的华商网做搜索,第一次用到了Lucene/Compass,到了现在搜索领域的热度远不如当年,技术上的确也有进步,对比大数据还是差了很多。ES最近我们也在用,的确是因为要把用户的使用情况这种使用日志记录下来,就是记录“某某在几月几日几点几分在系统上做了什么操作,就是系统使用日志”,为啥我们要记录这些,就是想记录之后,能够看到大家在系统上作业的过程,从流程到时间都会记录,还能让管理者更好的进行搜索也是避免一些操作型风险的产生。既然说ES跟数据库有相似之处,相似在:


数据库-ES
  • 索引(Index): 索引与关系型数据库实例(Database)相当。索引只是一个 逻辑命名空间,它指向一个或多个分片(shards)
  • 文档类型(Type):相当于数据库中的表的概念。每个文档在ES中都必须设定它的类型。文档类型使得同一个索引中在存储结构不同文档时,只需要依据文档类型就可以找到对应的参数映射(Mapping)信息,方便文档的存取。
  • 文档(Document) :相当于数据库中的row, 是可以被索引的基本单位。例如,你可以有一个的客户文档,有一个产品文档,还有一个订单的文档。文档是以JSON格式存储的。在一个索引中,您可以存储多个的文档。
    ES主要就这些基本概念了,弄明白很容易。别问为啥能进行搜索,因为这还要借助于分词工具比如“ik_max_word”等。
PUT my/_doc/1
 {
    "msg":"我爱北京天安门"
 }
POST /my/_search
{
    "query": {
        "match": {
            "msg": "北京"
        }
    }
}
PUT my/_mapping
{
    "properties": {
        "msg": {
            "type": "text",
            "analyzer": "ik_max_word"
        }
    }
}

只要我们给定我们的标准日志格式,就能够轻松获取所有的日志。ES只是存储了这些索引,更方便进行检索。前后联动的逻辑,我们不细说了,因为都一样。






Java的代码片段如下:


@RestController
public class LoginController {

    @Autowired
    private UserServiceImpl userService;

    /**
     * Login
     * @param response
     * @param request
     * @param user
     * @param model
     * @return
     */
    @PostMapping("/login")
    public ResponseResult Login(HttpServletResponse response , HttpServletRequest request, @RequestBody User user, Model model){
        ResponseResult responseResult=new ResponseResult();
        try {
            User my-user = userService.userlogin(request, response, user);
            if (user2!=null){
                responseResult.setState(200);
                responseResult.setMsg("登录成功!");
                return responseResult;
            }
        }catch (Exception e) {
            .....
        }
    }.....

UserServiceImpl.java
@Service
public class UserServiceImpl{
    @Autowired
    private UserDao userDao;

    private Map UserLogin = new HashMap<>();
    @Resource
    private KafkaTemplate kafkaTemplate;
    /**
     * 登录
     * @param request
     * @param response
     * @param u
     * @return
     */
    public User userlogin(HttpServletRequest request, HttpServletResponse response, User u){
        //查询登录是否成功
        User user=userDao.findByUsernameAndPassword(u.getUsername(),u.getPassword());
        //判断user是否为空
        if(user==null){
            return null;
        }
       kafkaTemplate.send("Kafka.topic.user", user.toString());
        return user;
    } .....

只要再写个Consumer消费一下消息,并且把消息的内容ES一下即可:

KafkaConsumer consumer = new KafkaConsumer<>(props);
consumer.subscribe(Collections.singletonList("Kafka.topic.user"));

说白了就是这么个过程


2021-02-14 情人节关于ES的思考_第1张图片
VUE->Spring Controller - Kafka->ES

当然,你完全可以通过Logstash来完成这件事,也不复杂,还是ELK的精髓所在。
日志的来源还是靠客户端的事件获取。ES的shards是用来做集群使用的,关于集群ES倒是用不上Zookeeper了,因为自己干的就是这么个集群的事情,用分片这个词更恰当。ES可以把一个完整的索引分成多个分片,这样的好处是可以把一个大的索引拆分成多个,分布到不同的节点上。构成分布式搜索。分片的数量只能在索引创建前指定,而且索引创建后不能更改。除了分片,ES还提供Replicas,代表了索引副本,副本的作用一是提高系统的容错性,当某个节点某个分片损坏或丢失时可以从副本中恢复。二是提高ES的查询效率,能够自动对搜索请求进行负载均衡(设计的的确巧妙)。当然在实际使用的场景下,一些基本的设置还是要注意的,比如:

  • 内存:特别是机器内存大于64G的时候,还有GC,另外像Query Cache的设置,是否需要手动Flush,避免使用脚本来对ES进行线上的操作等等。
    总之,还是要在实际场景中去使用,技术才会有价值,好吧还是祝大家情人节快乐。

你可能感兴趣的:(2021-02-14 情人节关于ES的思考)