如何将mysql的数据同步到es
1、使用Canal:Canal是阿里巴巴开源的一款基于MySQL数据库增量日志解析和同步的工具。Canal可以将MySQL中的数据同步到ES中,支持多种数据格式和数据源。
2、使用自定义脚本:可以编写自定义脚本,通过MySQL的JDBC驱动连接MySQL数据库,读取数据并将数据写入ES中。这种方式需要自己编写代码,但是可以根据自己的需求进行定制化开发。
redis的时间复杂度说一下
时间复杂度大小的比较:
O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n)
keys *这种命令肯定是要慎用的,时间复杂度高的命令要慎用,并发高的耗时命令要慎用,减少大对象的处理,String类型set,get时间复杂度为O(1),hash,list,set,sorted set
1.负责的项目的模块的业务场景以及实际解决问题
2.线程池 核心参数 执行流程
线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler);
1、 corePoolSize :当有新任务时,如果线程池中线程数没有达到线程池的基本大小,则会创建新的线程执行任务,否则将任务放入阻塞队列。当线程池中存活的线程数总是大于 corePoolSize 时,应该考虑调大 corePoolSize。
2、 maximumPoolSize :当阻塞队列填满时,如果线程池中线程数没有超过最大线程数,则会创建新的线程运行任务。否则根据拒绝策略处理新任务。非核心线程类似于临时借来的资源,这些线程在空闲时间超过 keepAliveTime 之后,就应该退出,避免资源浪费。
3、 BlockingQueue :存储等待运行的任务。
4、 keepAliveTime :非核心线程空闲后,保持存活的时间,此参数只对非核心线程有效。设置为0,表示多余的空闲线程会被立即终止。
5、 TimeUnit :时间单位
6、 ThreadFactory :每当线程池创建一个新的线程时,都是通过线程工厂方法来完成的。在
ThreadFactory 中只定义了一个方法 newThread,每当线程池需要创建新线程就会调用它。
7、 RejectedExecutionHandler :当队列和线程池都满了的时候,根据拒绝策略处理新任务。
执行流程:
提交任务之后,线程池会首先尝试着交给核心线程池中的线程来执行,核心线程是有限的,所以必须要由任务队列来缓存待执行的任务,如果任务队列也满了,这个时候线程池中剩下的线程(除核心线程以外的线程)就会启动来帮助核心线程执行任务。如果线程数已达到上限,这时就没法正常处理新到的任务,新的任务就会被交给饱和策略(拒绝策略)来处理了。
拒绝策略:
3.JVM内存模型 堆内存新生代老年代相关问题
在JDK1.8版本废弃了永久代,替代的是元空间(MetaSpace),元空间与永久代上类似,都是方法区的实现,他们最大区别是:元空间并不在JVM中,而是使用本地内存。
元空间有注意有两个参数:
堆内存溢出:
在年轻代中经过GC后还存活的对象会被复制到老年代中。当老年代空间不足时,JVM会对老年代进行完全的垃圾回收(Full GC)。如果GC后,还是无法存放从Survivor区复制过来的对象,就会出现OOM(Out of Memory)。
OOM(Out of Memory)异常常见有以下几个原因:
1)老年代内存不足:java.lang.OutOfMemoryError:Javaheapspace
2)永久代内存不足:java.lang.OutOfMemoryError:PermGenspace
3)代码bug,占用内存无法及时回收。
OOM在这几个内存区都有可能出现,实际遇到OOM时,能根据异常信息定位到哪个区的内存溢出。
可以通过添加个参数-XX:+HeapDumpOnOutMemoryError,让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后分析。
4.mysql调优实操
java.lang.NullPointerException 空指针
java.lang.ClassCastException 类型转换
java.lang.IllegalArgumentException 参数不合法
java.lang.IndexOutOfBoundsException 数组越界
java.lang.NumberFormatException 字符串转数字
java.lang.ClassNotFoundException 加载时找不到类定义
java.io.IOException 输入/输出异常的类
java.lang.OutOfMemoryError 内存泄露
6.spring框架bean的生命周期和加载的过程
自动装配:
Spring Boot 通过@EnableAutoConfiguration
开启自动装配,通过 SpringFactoriesLoader 最终加载META-INF/spring.factories
中的自动配置类实现自动装配,自动配置类其实就是通过@Conditional
按需加载的配置类,想要其生效必须引入spring-boot-starter-xxx
包实现起步依赖
Spring bean生命周期:
Bean 加载流程大致有三个阶段,分别是实例化 createBeanInstance() 、属性填充 populateBean() 和 初始化 initializeBean()
7.Linux命令 说五个 然后问了线上Jstack排查问题的命令
top、top -Hp pid
jmap -heap pid
jmap -dump:format=b,file=xxx.dump pid
jmap -histo:live pid | more
jstack -l pid> ./xxx
jstat -gc pid 5000
mysql的索引数据结构
在 MySQL
中使用较多的索引有 Hash 索引
,B+ 树索引
等,而我们经常使用的 InnoDB
存储引擎的默认索引实现为:B+ 树索引
Hash 索引
和 B+ 树索引
的底层实现原理:
hash索引
底层就是 hash表
,进行查找时,调用一次 hash
函数就可以获取到相应的键值,之后进行回表查询
获得实际数据。B+ 树
底层实现是多路平衡查找树。对于每一次的查询都是从根节点出发,查找到叶子节点方可以获得所查键值,然后根据查询判断是否需要回表查询数据。那么可以看出他们有以下的不同:
hash索引
进行等值查询更快(一般情况下),但是却无法进行范围查询。hash索引
中经过 hash函数
建立索引之后,索引的顺序与原顺序无法保持一致,不能支持范围查询。而 B+树
的的所有节点皆遵循(左节点小于父节点,右节点大于父节点,多叉树也类似
),天然支持范围。hash索引
不支持使用索引进行排序,原理同上。hash索引
不支持模糊查询以及多列索引的最左前缀匹配。原理也是因为 hash函数
的不可预测。hash索引
任何时候都避免不了回表查询数据,而B+树
在符合某些条件(聚簇索引,覆盖索引等)的时候可以只通过索引完成查询。hash索引
虽然在等值查询上较快,但是不稳定。性能不可预测,当某个键值存在大量重复的时候,发生 hash碰撞
,此时效率可能极差。而 B+树
的查询效率比较稳定,对于所有的查询都是从根节点到叶子节点,且树的高度较低。因此,在大多数情况下,直接选择 B+ 树
索引可以获得稳定且较好的查询速度。而不需要使用 hash索引
hashMap的原理
HashMap采用Entry数组来存储key-value对,每一个键值对组成了一个Entry实体,Entry类实际上是一个单向的链表结构,它具有Next指针,可以连接下一个Entry实体。 只是在JDK1.8中,链表长度大于8的时候,链表会转成红黑树。
在调用 HashMap 的 put 方法添加元素时,会对key的hashCode()做hash运算,计算index; 如果没碰撞直接放到bucket里; 如果碰撞了,以链表的形式存在buckets后; 如果碰撞导致链表过长(大于等于TREEIFY_THRESHOLD),就把链表转换成红黑树(JDK1.8中的改动); 如果节点已经存在就替换old value(保证key的唯一性) 如果bucket满了(超过load factor*current capacity),就要resize。
在调用 HashMap 的 get 方法获取元素时,会对key的hashCode()做hash运算,计算index; 如果在bucket里的第一个节点里直接命中,则直接返回; 如果有冲突,则通过key.equals(k)去查找对应的Entry。
消息中间件
消息丢失
1)、生产方发送消息时,要try...catch,在catch中捕获异常,并将MQ发送的关键内容记录到日志表中,日志表中要有消息发送状态,若发送失败,由定时任务定期扫描重发并更新状态;
2)、生产方publisher必须要加入确认回调机制,确认成功发送并签收的消息,如果进入失败回调方法,就修改数据库消息的状态,等待定时任务重发;
3)、消费方要开启手动签收ACK机制,消费成功才将消息移除,失败或因异常情况而尚未处理,就重新入队。
其实这就是前面阐述两个概念时已经讲过的内容,也是接近100%消息投递的企业级方案之一,主要目的就是为了解决消息丢失的问题。
消息重复
1)、消费方业务接口做好幂等;
2)、消息日志表保存MQ发送时的唯一消息ID,消费方可以根据这个唯一ID进行判断避免消息重复;
3)、消费方的Message对象有个getRedelivered()方法返回Boolean,为TRUE就表示重复发送过来的。
我这里只推荐第一种,业务方法幂等这是最直接有效的方式,(2)还要和数据库产生交互,(3)有可能导致第一次消费失败但第二次消费成功的情况被砍掉。
上线之后需要关注什么问题,怎么解决
延迟,流量,错误,性能,应该接入监控告警系统如Skywalking,收集日志,做分布式系统的链路追踪