Elastricsearch,通常用来收集日志,但其实他还有其他用处,之前我们用到这个,存储用户信息,是最简单的userinfo,就只做用户展示等等,以及管理后台的用户查询,不做业务相关的处理等等,再加上用户体量挺大(类似每天进行消费的新用户非常之多,但是可能一段时间内再不打开使用了。但是数据必须永久保留,这种模式就导致,有好多非活跃用户,大量存在,但是数据你必须永久保存,直到你整个产品线砍掉。)业务库的话,用的常规的MySQL,用户的数据信息是直接保存进去的,但是,如果只是客户端用户中心的信息展示,或者对应管理后台,运营人员查询一些基础信息,甚至bi报表端,查询一下总用户数量啦,消费人数啦等等(总所周知,mysql的InnnoDB引擎,count查询是扫全表的。不要杠有其他优化方式,你杠就是你对),其实使用es进行查询,会非常迅速并且简单的。
所以整体逻辑就是,用户注册进去,数据正常写入业务库,同时有另外一个程序,异步的从业务库往es里同步数据。基本时差没几秒钟的。同时为了防止新用户从客户端登录进去,要查看自己的用户信息,出现几秒的延迟,所以我们在查询用户信息的时候,都是首先从es查询,查询不到,再去redis里查询,redis里也不存在,再去业务库查询,查到数据后,直接加一个几分钟的redis缓存(至于几分钟,可以自己功能新上线后,观察一下线上情况,再做调整)。
注意这里,后端从业务库查询到数据后,只加redis就可,不用自己往es里插入。这个是为了做功能的解耦,因为我们上了微服务,某个服务就单独负责一块东西。往es里同步数据是另外一个服务的活,不要掺和到一起。
这样基本就没啥太大问题了。如果想做容灾预警,防止缓存穿透啦,或者es服务挂掉了,压力全给到mysql的话,还可以设置邮件预警报告,因为redis缓存有几分钟过期的一个设置,那么我们就可以做一个简单的计数器,redis被短时间内多次过期然后重新插入的话,就发邮件警报。
至于这个计数器,也可以基于redis做一下,这里我大致说一下思路。在加缓存之前,再基于用户ID+一些参数设置一个key,过期时间就是你想要的时间范围,假设2个小时,那你ttl就设置成7200,然后给这个key的value做次数的累加,被调用一次,就数字加1,然后当这个值大于等于20的时候,就发邮件提醒。以上配置仅供参考,主要还是需要配合自己的业务需求和实际生产环境的运行状态来自己调整。
以上是客户端的后端程序的处理逻辑,因为用户端是需要实时查看到自己的数据的,所以需要上边的这些复杂处理来保证数据安全,如果是管理后台,或者bi,有几分钟的数据延迟,其实是可以接受的,所以管理后台和bi直接走es就可。
这样一通操作下来,基本查询用户信息,就是几十毫秒的事情。