mysql数据结构

1. mysql数据库

  • 数据库是 “按照数据结构来组织、存储和管理数据的仓库”。是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合
  • MySQL 是一款安全、跨平台、高效的,并与 PHP、Java 等主流编程语言紧密结合的数据库系统。该数据库系统是由瑞典的 MySQL AB 公司开发、发布并支持,由 MySQL 的初始开发人员 David Axmark 和 Michael Monty Widenius 于 1995 年建立的。
  • MySQL 的象征符号是一只名为 Sakila 的海豚,代表着 MySQL 数据库的速度、能力、精确和优秀本质。

Mqtt面试题

  1. MQTT简介
    • (1)MQTT(Message Queuing Telemetry Transport,消息队列遥测传输协议),是一种基于发布/订阅(publish/subscribe)模式的”轻量级”通讯协议,该协议构建于TCP/IP协议上,由IBM在1999年发布。MQTT最大优点在于,可以以极少的代码和有限的带宽,为连接远程设备提供实时可靠的消息服务。作为一种低开销、低带宽占用的即时通讯协议,使其在物联网、小型设备、移动应用等方面有较广泛的应用。
    • (2)MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。MQTT协议是轻量、简单、开放和易于实现的,这些特点使它适用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。其在,通过卫星链路通信传感器、偶尔拨号的医疗设备、智能家居、及一些小型化设备中已广泛使用。
  2. MQTT和HTTP的区别?
    • (1)设计和消息传递:MQTT以数据为中心,HTTP以文档为中心。HTTP是用于客户端—服务器计算的请求—响应协议,并不总是针对移动设备进行优化。MQTT在这些术语中的主要优点是轻量级(MQTT将数据作为字节数组传输)和发布/订阅模型,这使其非常适合资源受限的设备并有助于节省电池。此外,发布/订阅模型为客户提供了彼此独立的存在,增强了整个系统的可靠性。当一个客户端出现故障时,整个系统可以继续正常工作。
    • (2)速度和交付:根据3G网络的测量结果,MQTT的吞吐量比HTTP快93倍。
      此外,与HTTP相比,MQTT协议确保了高传输保证。有3个级别的服务质量:
      – 最多一次:保证尽力交付。
      – 至少一次:保证消息至少传送一次。但是消息也可以不止一次传递。
      – 恰好一次:保证每个消息只被对方接收一次
      MQTT还为用户提供Last will&Testament和Retained消息的选项。第一个意味着在客户端意外断开连接的情况下,所有订阅的客户端都将从代理获得消息。保留消息意味着新订阅的客户端将立即获得状态更新。
      HTTP协议没有这些功能。
    • (3)复杂性和消息大小:

Spring事务的传播机制

  • REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。
  • SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。
  • MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。
  • REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
  • NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
  • NEVER:无事务执行,如果当前有事务则抛出Exception。
  • NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。

事务的隔离机制

事务是以可控的方式对数据资源进行访问的一组操作。其属性包括原子性、一致性、隔离性和持久性,也就是常说的ACID。其中,隔离性是针对数据资源的并发访问,规定了各个事务之间相互影响的程度。个人认为这是事务的4个特性里面,比较难理解的一个。
事实上,事务的隔离性可以分为4种类型的隔离级别:Read Uncommitted,Read Committed, Repeatable Read和Serilization。这4个类型的隔离级别在应对数据资源并发访问可能出现的问题时的要求不一样。数据资源并发访问时可能出现的问题有:

  1. 脏读:如果一个事务A对数据进行了更改,但是还没有提交,而另一个事务B就可以读到事务A尚未提交的更新结果。这样,当事务A进行回滚时,那么事务B开始读到的数据就是一笔脏数据。
  2. 不可重复读:同一个事务在事务过程中,对同一个数据进行读取操作,读取到的结果不同。例如,事务B在事务A的更新操作前读到的数据,跟在事务A提交此更新操作后读到的数据,可能不同。要避免不可重复读,需要将事务所操作的记录都加上锁,不允许其他事务对此记录进行写操作。
  3. 幻读:同样一个查询在整个事务中多次执行,查询所得的结果不同。例如,事务A对全部记录做了更新操作,尚未提交前,事务B又插入了一条记录,那么事务A再次读取数据库时,会发现还有一条记录(即事务B新插入的记录)没有做更新。

也可以理解成:
要避免脏读,需要控制在事务没有提交更新前,其他事务无法看到此事务的更新结果。
要避免脏读,需要控制在事务没有提交更新前,其他事务无法看到此事务的更新结果。
要避免幻读,需要将整张表都锁住了。
对于隔离级别:
Read Uncommitted:(读取未提交)最低的隔离级别。一个事务可以读取另一个事务没有提交的更新结果。
Read Committed:(读取已提交)一个事务的更新操作只有在提交了之后,才会被另一个事务读取到同一笔数据更新后的结果
Repeatable Read:(可重复读)在整个事务中,对同一笔数据的读取结果是相同的,不管其他事务是否同时在对这笔数据进行更新,也不管这笔更新是否提交。
Serilizable:(序列化)所有的事务操作都必须串行操作。这种隔离级别最高,但是牺牲了系统的并发性。通常会使用其他的隔离级别加上相应的并发锁机制来控制对数据的访问。
事务的隔离级别与数据资源并发访问时的问题的对应关系可以如下表所示:

名称 脏读 不可重复读 幻读
Read Uncommited 可能 可能 可能
Read commited 不可能 可能 可能
Repeatable Read 不可能 不可能 可能
Serilization 不可能 不可能 不可能

总体来说,隔离级别与系统并发性成反比,与数据一致性成正比。一般数据库默认的隔离级别是:ReadCommited,不同数据库支持的隔离级别可能不一样。为了实现数据一致性和系统并发行的平衡,一般会采取Read Committed加上锁表等方式来进行。

索引

什么是索引?

索引其实是一种数据结构,能够帮助我们快速的检索数据库中的数据

索引的优缺点?

  • 优点
    1. 提高数据检索的效率,降低数据库IO成本。
    2. 通过索引对数据进行排序,降低数据的排序成本,降低CPU的消耗。
  • 缺点
    1. 建立索引需要占用物理空间
    2. 会降低表的增删改的效率,因为每次对表记录进行增删改,需要进行动态维护索引,导致增删改时间变长

什么情况下需要建索引?

  1. 主键自动创建唯一索引
  2. 较频繁的作为查询条件的字段
  3. 查询中排序的字段,查询中统计或者分组的字段

什么情况下不需要建索引?

  1. 表记录太少的字段
  2. 经常增删改的字段
  3. 唯一性太差的字段,不适合单独创建索引。比如性别,民族,政治面貌

索引有哪几种分类?

MySQL主要的几种索引类型:1.普通索引 2.唯一索引 3.主键索引 4.组合索引 5.全文索引。

  • 普通索引: 是最基本的索引,它没有任何限制
  • 唯一索引: 索引列的值必须唯一,但允许有空值。如果是组合索引,则列值的组合必须唯一
  • 主键索引: 是一种特殊的唯一索引,一个表只能有一个主键,不允许有空值。
  • 联合索引: 一个索引包含多个列,实际开发中推荐使用组合索引。
  • 全文索引: 全文搜索的索引。FULLTEXT 用于搜索很长一篇文章的时候,效果最好。只能用于InnoDB或MyISAM表,只能为CHAR、VARCHAR、TEXT列创建。
  • 聚簇索引: 将数据存储与索引放到了一块,找到索引也就找到了数据
  • 非聚簇索引: 将数据存储于索引分开结构,索引结构的叶子节点指向了数据的对应行,myisam通过key_buffer把索引先缓存到内存中,当需要访问数据时(通过索引访问数据),在内存中直接搜索索引,然后通过索引找到磁盘相应数据,这也就是为什么索引不在key buffer命中时,速度慢的原因
  • 覆盖索引: 覆盖索引是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖

索引的数据结构有哪些?

Hash索引和B+树索引的区别?

为什么B+树比B树更适合实现数据库索引?

聚集索引相对于非聚集索引的区别?

什么是回表查询?

什么是覆盖索引?

什么是最左匹配原则?

索引失效场景有哪些?

  • 组合索引未使用最左前缀,例如组合索引(age,name),where name=’张三’不会使用索引;
  • or会使索引失效。如果查询字段相同,也可以使用索引。例如where age=20 or age=30(索引生效),where age=20 or name=‘张三’(这里就算你age和name都单独建索引,还是一样失效);
  • 如果列类型是字符串,不使用引号。例如where name=张三(索引失效),改成where name=‘张三’(索引有效);
  • like未使用最左前缀,where A like ‘%China’;
  • 在索引列上做任何操作计算、函数,会导致索引失效而转向全表扫描;
  • 如果mysql估计使用全表扫描要比使用索引快,则不使用索引;

索引的设计原则?

限流-熔断-服务降级

1. 限流

当系统的处理能力不能应对外部请求的突增流量时,为了不让系统奔溃,必须采取限流的措施。

1.1 限流指标

  • TPS 服务器每秒处理的事务数量
  • HPS 服务器每秒处理的请求数量
  • QPS 服务器每秒处理的查询请求数量

1.2 限流方案

参考 《接口限流》 文章

2. 服务降级

服务降级一般是指在服务器压力剧增的时候,根据实际业务使用情况以及流量,对一些服务和页面有策略的不处理或者用一种简单的方式进行处理,从而释放服务器资源的资源以保证核心业务的正常高效运行

3. 服务熔断

当服务A调⽤的某个服务B不可⽤时,上游服务A为了保证⾃⼰不受影响,从⽽不再调⽤服务B,直接返回⼀个结果, 减轻服务A和服务B的压⼒,直到服务B恢复

接口幂等性

1. 什么是接口幂等性

在HTTP/1.1中,对幂等性进行了定义。它描述了一次和多次请求某一个资源对于资源本身应该具有同样的结果(网络超时等问题除外),即第一次请求的时候对资源产生了副作用,但是以后的多次请求都不会再对资源产生副作用。

这里的副作用是不会对结果产生破坏或者产生不可预料的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同。

2. 为什么需要实现幂等性

在接口调用时一般情况下都能正常返回信息不会重复提交,不过在遇见以下情况时可以就会出现问题,如:

  • 前端重复提交表单:在填写一些表格时候,用户填写完成提交,很多时候会因网络波动没有及时对用户做出提交成功响应,致使用户认为没有成功提交,然后一直点提交按钮,这时就会发生重复提交表单请求。

  • 用户恶意进行刷单:例如在实现用户投票这种功能时,如果用户针对一个用户进行重复提交投票,这样会导致接口接收到用户重复提交的投票信息,这样会使投票结果与事实严重不符。

  • 接口超时重复提交:很多时候 HTTP 客户端工具都默认开启超时重试的机制,尤其是第三方调用接口时候,为了防止网络波动超时等造成的请求失败,都会添加重试机制,导致一个请求提交多次。

  • 消息进行重复消费:当使用 MQ 消息中间件时候,如果发生消息中间件出现错误未及时提交消费信息,导致发生重复消费。

sentinel

Sentinel是什么?

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性

Sentinel具有以下特征

  • 丰富的应用场景: Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
  • 完备的实时监控: Sentinel 同时提供实时的监控功能。您可以在控制台中看到接入应用的单台机器秒级数据,甚至 500 台以下规模的集群的汇总运行情况。
  • 广泛的开源生态: Sentinel 提供开箱即用的与其它开源框架/库的整合模块,例如与 Spring Cloud、Dubbo、gRPC 的整合。您只需要引入相应的依赖并进行简单的配置即可快速地接入 Sentinel。
  • 完善的 SPI 扩展点: Sentinel 提供简单易用、完善的 SPI 扩展接口。您可以通过实现扩展接口来快速地定制逻辑。例如定制规则管理、适配动态数据源等。

    服务使用中的各种问题

  • 服务雪崩
  • 服务降级
  • 服务熔断
  • 服务限流

gitlab安装

机器配置要求较高,至少需要2G内存

1. 配置程序包管理系统(yum)

1
vi /etc/yum.repos.d/gitlab-ce.repo
  • 将以下内容复制到文件中
    1
    2
    3
    4
    5
    [gitlab-ce]
    name=Gitlab CE Repository
    baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
    gpgcheck=0
    enabled=1

2. 更新本地缓存

1
yum makecache

3. 安装gitlab

1
yum install -y gitlab-ce

4. 修改拉代码的地址换成自己的ip和端口

1
vi /etc/gitlab/gitlab.rb

更改以下配置

1
external_url 'http://ip:port'

5. 刷新配置

1
gitlab-ctl reconfigure

6. 基本命令

1
2
3
4
5
gitlab-ctl start
gitlab-ctl stop
gitlab-ctl restart
gitlab-ctl status
gitlab-ctl enable

rabbitmq安装

rabbitmq是由erlang语言编写的,安装之前必须先安装erlang环境,并且两者版本需要匹配
rabbitmq依赖于socat,所以也要先安装socat
安装包版本中的el7,el8代表不同的系统,安装的时候要注意

1. 单机版安装

  1. erlang安装
1
wget --content-disposition https://packagecloud.io/rabbitmq/erlang/packages/el/8/erlang-24.2-1.el8.x86_64.rpm/download.rpm
1
rpm -ivh erlang-24.2-1.el8.x86_64.rpm
  1. socat安装
1
yum install socat -y
  1. rabbitmq安装
1
wget --content-disposition https://packagecloud.io/rabbitmq/rabbitmq-server/packages/el/8/rabbitmq-server-3.9.12-1.el8.noarch.rpm/download.rpm
1
rpm -ivh rabbitmq-server-3.9.12-1.el8.noarch.rpm
  1. 基本命令
1
2
3
4
5
systemctl start rabbitmq-server
systemctl status rabbitmq-server
systemctl enable rabbitmq-server
systemctl stop rabbitmq-server
systemctl restart rabbitmq-server
  1. web管理界面插件安装
1
rabbitmq-plugins enable rabbitmq_management

访问 http://ip:15672 ,用默认账号密码guest登录,出现权限问题 默认情况只能在 localhost 本机下访问,所以需要添加一个远程登录的用户

  • 创建账号和密码
1
rabbitmqctl add_user admin 123456
  • 设置用户角色
1
rabbitmqctl set_user_tags admin administrator
  • 为用户添加资源权限
1
rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"

** 权限博客参考**

  1. 其他插件安装(非必须,以延时队列插件为例)

将下载好的延时队列插件移动到指定目录 下载地址

1
mv rabbitmq_delayed_message_exchange-3.9.0.ez /usr/lib/rabbitmq/lib/rabbitmq_server-3.9.12/plugins/

开启延时队列功能

1
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
  1. 卸载
1
2
yum -y remove rabbitmq-server.noarch
rm -rf /var/lib/rabbitmq/ && rm -rf /var/log/rabbitmq/ && rm -rf /usr/local/rabbitmq/

2. 集群安装(镜像模式)

服务器准备

服务器 端口 说明
192.168.72.128 5672 硬盘节点
192.168.72.131 5672 内存节点
192.168.72.132 5672 内存节点
  1. 禁用SELINUX,为每台机器执行以下操作
1
vi /etc/selinux/config

修改下面配置

1
SELINUX=disabled
  1. 修改三台机器的host文件
1
vi /etc/hosts

添加以下内容,s1,s2,s3分别为三个节点的虚拟名称,可自定义

1
2
3
192.168.186.128 s1
192.168.186.131 s2
192.168.186.132 s3
  1. 重启服务器

  2. 为每台机器安装rabbitmq和web插件,并启动(不要创建用户)

  3. 设置每个节点的cookie文件相同

  • 先将文件赋予写权限
1
chmod 600 /var/lib/rabbitmq/.erlang.cookie
  • 更改cookie内容,节点保持一致
1
vi /var/lib/rabbitmq/.erlang.cookie
  • 重启服务
1
systemctl restart rabbitmq-server
  1. 配置节点

s1为硬盘节点,s2和s3是内存节点,所以分别在s2和s3上设置如下内容

1
2
3
rabbitmqctl stop_app
rabbitmqctl join_cluster --ram rabbit@s1
rabbitmqctl start_app
  1. 在s1服务器创建用户(用户会自动同步到s2,s3)

  2. 在s1服务器安装其他所需插件

3. 其他

|