ETCD高可用架构涉及常用功能整理

ETCD高可用架构涉及常用功能整理

  • 1. etcd的高可用系统架构和相关组件
    • 1.1 Quorum机制
    • 1.2 Raft协议
  • 2. etcd的核心参数
    • 2.1 常规配置
    • 2.2 特殊优化配置
      • 2.2.1 强行拉起新集群 --force-new-cluster
      • 2.2.2 兼容磁盘io性能差
      • 2.2.3 etcd存储quota
  • 3. etcd常用命令
    • 3.1 常用基础命令
      • 3.1.1 列出特定前缀的key和value
      • 3.1.1 重新设置value
      • 3.1.1 删除key
    • 3.2 常用运维命令
      • 3.2.1 检查集群member信息
      • 3.2.2 检查集群member增加、删除
      • 3.2.3 检查节点状态
      • 3.2.4 检查集群状态
      • 3.2.5 数据备份还原
  • 4. 事务性
    • 4.1 数据写流程
    • 4.2 数据读流程
    • 4.3 MVCC机制
      • 4.3.1 并发读写事务的问题
      • 4.3.2 锁机制
      • 4.3.3 MVCC进行事务隔离
      • 4.3.4 etcd中MVCC实现
  • 5. 疑问和思考
    • 5.1 etcd不擅长处理哪些场景?
    • 5.2 etcd和zk有什么异同?
  • 6. 参考文档

探讨etcd的系统架构以及以及整体常用的命令和系统分析,本文主要探讨高可用版本的etcd集群,并基于日常工作中的沉淀进行思考和整理。更多关于分布式系统的架构思考请参考文档关于常见分布式组件高可用设计原理的理解和思考


1. etcd的高可用系统架构和相关组件

etcd在产品设计上,面对的存储数据量比较小,一台etcd机器就能够满足数据的存储需求,因此在集群的架构设计上,使用镜像模式进行数据高可用,通过Raft 协议进行选举leader,从而满足集群的高可用和数据一致性要求。

etcd的系统架构如下
在这里插入图片描述

相关核心的组件和角色作用如下

角色数量角色作用备注
Leader有且必须只有1个它会发起并维护与各Follwer及Observer间的心跳,所有的写操作必须要通过Leader完成再由Leader将写操作广播给其它服务器通过内部选举选择出leader
Follower多个会响应Leader的心跳,可直接处理并返回客户端的读请求,同时会将写请求转发给Leader处理,并且负责在Leader处理写请求时对请求进行投票和Observer统称为Learner
Learner多个作用跟Follow相同,但是没有投票权和Follower统称为Learner

在这里插入图片描述

1.1 Quorum机制

Quorum机制(有效个数)模式:指分布式系统的每一次修改都要在大多数(超过半数)实例上通过来确定修改通过。

产生Quorum机制(有效个数)的背景如下:

分布式系统的LC矛盾
在一个分布式存储系统中,用户请求会发到一个实例上。通常在一个实例上面执行的修改,需要复制到其他的实例上,这样可以保证在原实例挂了的情况下,用户依然可以看到这个修改。这就涉及到一个问题,究竟复制到多少个其他实例上之后,用户请求才会返回成功呢?如果复制的实例个数过多,那么请求响应时间就会更长;如果复制的实例过少,则这个修改可能会丢失。取得这个平衡性很重要,这也是分布式 PACELC 中的 L(Latency) 与 C(Consistency) 的取舍。

解决方案
当一个修改,被集群中的大部分节点(假设个数为N)通过之后,这个修改也就被这个集群所接受。这个 N 就是有效个数。假设集群数量为 n,那么 N = n/2 + 1.例如 n = 5,则 N = 3,从而应运而生Quorum机制(有效个数)

1.2 Raft协议

etcd 集群使用 Raft 协议保障多节点集群状态下的数据一致性。etcd 是使用 Go 语言对 Raft 协议一种实现方式。

在 Raft 体系中,有一个强 Leader,由它全权负责接收客户端的请求命令,并将命令作为日志条目复制给其他服务器,在确认安全的时候,将日志命令提交执行。当 Leader 故障时,会选举产生一个新的 Leader。在强 Leader 的帮助下,Raft将一致性问题分解为了三个子问题:

  • Leader 选举:当已有的leader故障时必须选出一个新的leader。
  • 日志复制:leader接受来自客户端的命令,记录为日志,并复制给集群中的- 其他服务器,并强制其他节点的日志与leader保持一致。
  • 安全 safety 措施:通过一些措施确保系统的安全性,如确保所有状态机按照相同顺序执行相同命令的措施。
    解这三个子问题的过程,保障了数据的一致。

2. etcd的核心参数

2.1 常规配置

etcd常用配置

    - --advertise-client-urls=https://xx.xx.xx.xx:2379- --cert-file=/etc/kubernetes/pki/etcd/server.crt- --client-cert-auth=true- --data-dir=/data/var/lib/etcd- --initial-advertise-peer-urls=https://xx.xx.xx.xx:2380# 所有集群节点- --initial-cluster=xx.xx.xx.xx=https://xx.xx.xx.xx:2380,xx.xx.xx.xx=https://xx.xx.xx.xx:2380,xx.xx.xx.xx=https://xx.xx.xx.xx:2380,xx.xx.xx.xx=https://xx.xx.xx.xx:2380,xx.xx.xx.xx=https://xx.xx.xx.xx:2380- --initial-cluster-state=new- --key-file=/etc/kubernetes/pki/etcd/server.key- --listen-client-urls=https://127.0.0.1:2379,https://xx.xx.xx.xx:2379- --listen-metrics-urls=http://0.0.0.0:2381- --listen-peer-urls=https://xx.xx.xx.xx:2380- --name=xx.xx.xx.xx- --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt- --peer-client-cert-auth=true- --peer-key-file=/etc/kubernetes/pki/etcd/peer.key- --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt- --snapshot-count=10000- --quota-backend-bytes=8589934592- --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt- --cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384,TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA

更多参数可以参考文档 etcd 配置标记

2.2 特殊优化配置

2.2.1 强行拉起新集群 --force-new-cluster

强行启动一个etcd集群,只有在集群崩溃的应急恢复时使用,配合2个参数

  • –initial-cluster=xx.xx.xx.xx=https://xx.xx.xx.xx:2380(只能设置1个节点)
  • –initial-cluster-state=new
    一起使用,可以拉起一个单节点集群。后续通过member add的方式将节点加入集群进行应急恢复,具体操作可以参考 ETCD单节点故障应急恢复

2.2.2 兼容磁盘io性能差

如果磁盘的io性能很差,etcd集群可能会由于读写过慢导致集群崩溃,可以通过调整如下2个参数进行兼容

--heartbeat-interval=5000
--election-timeout=30000

2.2.3 etcd存储quota

etcd 默认默认设置了2GB 的存储配额,大概能够支撑存储两百万文件的元数据,可以通过 --quota-backend-bytes 选项进行调整,官方建议不要超过8GB。 当数据量达到配额导致无法写入时,可以通过手动压缩( etcdctl compact )和整理碎片( etcdctl defrag )的方式来减少容量。

--quota-backend-bytes=8589934592

3. etcd常用命令

利用etcd安装包中自带的etcdCli.sh命令,能够链接到etcd中,并进行相关的操作

# 连接本地etcd
./etcdCli.sh# 远程连接etcd
./etcdCli.sh -server xx.xx.xx.xx:2181

3.1 常用基础命令

整理日常操作etcd常用的命令,便于针对etcd的数据操作。由于etcd版本问题,目前主流使用的版本都是etcdv2和etcdv3两个版本。通常主流的命令都是使用v3版本,在本文中主要介绍v3版本的日常操作

3.1.1 列出特定前缀的key和value

# 列出所有的key
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  get /  --prefix --keys-only# 列出所有的key,value
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  get / --prefix# 列出前缀为/xx的所有key
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  get /xxx  --prefix --keys-only# 列出前缀为xx的所有key,value
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  get /xxx--prefix

3.1.1 重新设置value

# 设置对应的key和value
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  put /xxx  "xxxx"

3.1.1 删除key

# 设置对应的key和value
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key"  del /xxx

3.2 常用运维命令

用于日常运维命令,便于进行服务运维,提升系统稳定性。

3.2.1 检查集群member信息

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table member list

3.2.2 检查集群member增加、删除

增加节点信息

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table member add xx.xx.xx.xx --peer-urls="https://xx.xx.xx.xx:2380"

删除节点信息

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table member   remove ${memberid}

3.2.3 检查节点状态

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table endpoint health

–endpoints 列出所有需要检查的节点

3.2.4 检查集群状态

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table endpoint status

–endpoints 列出所有节点

3.2.5 数据备份还原

备份数据,备份的数据不包含节点信息

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table snapshot save snapshot.db

恢复数据,并基于恢复的数据启动一个单节点集群

ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert="/etc/kubernetes/pki/etcd/ca.crt" --cert="/etc/kubernetes/pki/etcd/server.crt" --key="/etc/kubernetes/pki/etcd/server.key" --write-out=table snapshot save snapshot.dbETCDCTL_API=3 etcdctl snapshot restore snapshot.db --name xx.xx.xx.xx  --initial-cluster xx.xx.xx.xx=https://xx.xx.xx.xx:2380 --initial-advertise-peer-urls https://xx.xx.xx.xx:2380 --data-dir /data/var/lib/etcd

–data-dir 是数据的保存目录,跟etcd的启动参数保持一致

4. 事务性

4.1 数据写流程

etcd的数据写流程,整体流程如下。
在这里插入图片描述

  1. 客户端发送写请求,通过负载均衡算法选取合适的 etcd 节点,发起 gRPC 调用。
  2. etcd server 的 gRPC Server 收到这个请求,经过 gRPC 拦截器拦截,实现 Metrics 统计和日志记录等功能。
  3. Quota 模块配额检查 db 的大小,如果超过会报etcdserver: mvcc: database space exceeded的告警,通过 Raft 日志同步给集群中的节点 db 空间不足,同时告警也会持久化到 db 中。etcd 服务端拒绝写入,对外提供只读的功能。
  4. 配额检查通过,KVServer 模块经过限速、鉴权、包大小判断之后,生成唯一的编号,这时才会将写请求封装为提案消息,提交给 Raft 模块。
  5. 写请求的提案只能由 Leader 处理(如果客户端链接到Follower会进行路由到Leader),获取到 Raft 模块的日志条目之后,Leader 会广播提案内容。WAL 模块完成 Raft 日志条目内容封装,当集群大多数节点完成日志条目的持久化,即将提案的状态变更为已提交,可以执行提案内容。
  6. Apply 模块用于执行提案,首先会判断该提案是否被执行过,如果已经执行,则直接返回结束;未执行过的情况下,将会进入 MVCC 模块执行持久化提案内容的操作。
  7. MVCC 模块中的 treeIndex 保存了 key 的历史版本号信息,treeIndex 使用 B-tree 结构维护了 key 对应的版本信息,包含了全局版本号、修改次数等属性。版本号代表着 etcd 中的逻辑时钟,启动时默认的版本号为 1。键值对的修改、写入和删除都会使得版本号全局单调递增。写事务在执行时,首先根据写入的 key 获取或者更新索引,如果不存在该 key,则会给予当前最大的 currentRevision 自增得到 revision;否则直接根据 key 获取 revision。
  8. 根据从 treeIndex 中获取到 revision 、修改次数等属性,以及 put 请求传递的 key-value 信息,作为写入到 boltdb 的 value,而将 revision 作为写入到 boltdb 的 key。同时为了读请求能够获取最新的数据,etcd 在写入 boltdb 时也会同步数据到 buffer。因此上文介绍 etcd 读请求的过程时,会优先从 buffer 中读取,读取不到的情况下才会从 boltdb 读取,以此来保证一致性和性能。为了提高吞吐量,此时提案数据并未提交保存到 db 文件,而是由 backend 异步 goroutine 定时将批量事务提交。
  9. Server 通过调用网络层接口返回结果给客户端。

总的来说,这个过程为客户端发起写请求,由 Leader 节点处理,经过拦截器、Quota 配额检查之后,KVServer 提交一个写请求的提案给 Raft 一致性模块,经过 RaftHTTP 网络转发,集群中的其他节点半数以上持久化成功日志条目,提案的状态将会变成已提交。接着 Apply 通过 MVCC 的 treeIndex、boltdb 执行提案内容,成功之后更新状态机。

整体的流程机制上,跟zk的类似,具体可以参考ZK高可用架构涉及常用功能整理。

4.2 数据读流程

相比写数据流程,读数据流程就简单得多;因为每台server中数据一致性都一样,所以随便访问哪台server读数据就行;没有写数据流程中请求转发、数据同步、成功通知这些步骤。

4.3 MVCC机制

4.3.1 并发读写事务的问题

我们知道,数据库并发场景有三种,分别为读-读、读-写和写-写。

  • 读-读没有问题,不存在线程安全问题,因此不需要并发控制;

  • 读-写和写-写都存在线程安全问题,读-写可能遇到脏读,幻读,不可重复读;写-写可能会存在更新丢失问题。

  • 脏读(读取未提交数据):无效数据的读出,是指在数据库访问中,事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。值得注意的是,脏读一般是针对于update操作的,通常解决的方式是使用行级锁

  • 不可重复读(前后多次读取,数据内容不一致):事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。值得注意的是,不可重复读一般是针对于update操作的,通常解决的方式是使用行级锁

  • 幻读(前后多次读取,数据总量不一致):事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。值得注意的是,幻读一般是针对于针对insert和delete操作,通常解决的方式是使用表级锁

总结下来,这3种并发控制的问题都是,事务A执行更新操作时,事务B内多次读的结果不一致,从而导致违背了事务的ACID原则。

4.3.2 锁机制

为了解决如上问题通常是通过锁机制实现,常用的是悲观锁和乐观锁
悲观锁和乐观锁。

  • 悲观锁: 为了保证事务的隔离性,就需要一致性锁定读。读取数据时给加锁,其它事务无法修改这些数据。修改删除数据时也要加锁,其它事务无法读取这些数据。

  • 乐观锁:相对悲观锁而言,乐观锁机制采取了更加宽松的加锁机制。悲观锁大多数情况下依靠数据库的锁机制实现,以保证操作最大程度的独占性。但随之而来的就是数据库性能的大量开销,特别是对长事务而言,这样的开销往往无法承受。乐观锁,大多是基于数据版本( Version )记录机制实现。

MVCC是一种乐观锁

4.3.3 MVCC进行事务隔离

曾经也一度困恼我,MVCC为什么能够解决这个问题,MVCC使用多版本记录数据值,但是如果读事务需要读取最新的数据时,通过MVCC,也不是不能解决在一次读事务中多次读的不一致问题吗?

没错,如果一个读事务一定要求多次读,都必须读取到最新的数据,MVCC地区不能解决这个问题,因为这不是MVCC能够作用的范围!!

后来我重新学习和理解了事务的ACID原则,具体的内容如下

ACID,是指数据库管理系统(DBMS)在写入或更新资料的过程中,为保证交易(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)。

这里并没有提到,读取的数据一定是最新的,只是要求一个读事务每次的结果都是可靠正确的,所以这就是MVCC的作用范围。读事务只需要读取到已经提交的历史最新版本,即可以保证事务的ACID!

事实上,在MySQL中MVCC只在REPEATABLE READ和READ COMMITTED两个隔离级别下工作。其他两个隔离级别都和MVCC不兼容,因为READ UNCOMMITTED总是读取最新的数据行,而不是符合当前事务版本的数据行,而SERIALIZABLE会对所有读取到的行都加锁。etcd的实现有些差异,但是整体上是一致的,etcd中没有mysql这样复杂的事务选择,因此能够通过MVCC解决读写并发的问题。

参考mysql的mvcc事务并发过程,如下
在这里插入图片描述
假设当前有个正在执行事务99,数据行的历史版本为事务id90(1,1)。

  1. 按照事务的开启时间,分别递增分配了100,101,102三个事务ID(trx id)
  2. 在SQL语句执行之前,事务A生成一致性视图【99,100】,事务B生成一致性视图【99,100,101】,事务C生成一致性视图【99,100,101,102】
  3. SQL语句的执行之前生成undo log,通过undo log可以生成历史版本数据快照,上图右侧历史版本数据。
  4. 事务A的查询执行时,当前数据版本为trx id:101,跟一致性视图【99,100】进行比较,101大于高水位不可见,通过undo log回退到trx id:102版本,102也大于高水位不可见,再回退一个版本到trx id:90,90低于低水位可见,所以事务A读取到的数据为(1.1)。

4.3.4 etcd中MVCC实现

这里不再赘述,可以参考 MVCC 在 etcd 中的实现

5. 疑问和思考

5.1 etcd不擅长处理哪些场景?

etcd擅长处理kv小量数据(v一般不能超过1M),基于etcd进行分布式锁、选主、服务发现等均有比较好的应用和实践。但是etcd不擅长处理大量数据的存储,通常需要注意不能在etcd路径下写入过多数据。事实上,etcd的官方建议,默认配置的是2G的Quotao,最大不能超过8G的数据存储。

5.2 etcd和zk有什么异同?

说实话,etcd和zk这两款产品实在太雷同了,基本上两者面对的使用场景基本上都是一致的,因此两个产品在是线上其实非常贴近。差异是etcd更贴近容器平台,zk更贴近大数据平台。其他的差别并太大,从使用方的角度来看,差别并不太大。值得一提的是,zk的对运维同学的友好度要比etcd友好一些,节点增加、剔除等步骤要简单很多。

6. 参考文档

  • etcd 配置标记
  • MVCC 在 etcd 中的实现
  • etcd官方文档

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/247289.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C++】wxWidgets编程的程序入口点

在wxWidgets中,程序的入口点通过wxIMPLEMENT_APP宏定义来设置,该宏会扩展为一个实现了main函数或者在Windows上是WinMain函数的代码。wxIMPLEMENT_APP宏与wxDECLARE_APP宏一起使用来设置基于wxWidgets的应用程序的启动代码。 使用wxIMPLEMENT_APP宏通常是…

day31WEB攻防-通用漏洞文件上传js验证mimeuser.ini语言特性

目录 1.JS验证 2.JS验证MIME 3.JS验证.user.ini 4.JS验证.user.ini短标签 (ctfshow154,155关) 5.JS验证.user.ini短标签过滤 [ ] 6.JS验证.user.ini短标签加过滤文件头 有关文件上传的知识 1.为什么文件上传存在漏洞 上传文件…

2024年数学建模美赛C题(预测 Wordle)——思路、程序总结分享

1: 问题描述与要求 《纽约时报》要求您对本文件中的结果进行分析,以回答几个问题。 问题1:报告结果的数量每天都在变化。开发一个模型来解释这种变化,并使用您的模型为2023年3月1日报告的结果数量创建一个预测区间。这个词的任何属性是否会…

【服务器Midjourney】创建部署Midjourney网站

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建MJ】 🌼1. 给服务器添加端口 🌼2. 使用Xshell连接服务器 🌼3. 安装docker 🌼4. 安装Midjourney程序 🌼5. 绑定域名+申请SSL证书 🌼6. 更新网站

分布式空间索引了解与扩展

目录 一、空间索引快速理解 (一)区域编码 (二)区域编码检索 (三)Geohash 编码 (四)RTree及其变体 二、业内方案选取 三、分布式空间索引架构 (一)PG数…

elementUI的el-select传递item对象或其他参数的2种方法

方法1 :value“item” 绑定对象 只要:value绑定item对象就可以 value-key"value" 必须是item里的一个属性&#xff0c;绑定值为对象类型时必填 <el-select v-model"value" placeholder"请选择" value-key"value" change"cha…

【产品经理从0到1】产品经理常用网站

1.产品社区类 人人都是产品经理 | 产品经理、产品爱好者学习交流平台 2.资讯新闻 虎嗅网(虎嗅网) 捕获互联网每个重要时刻 36kr(36氪 | 让创业更简单) 互联网最新最热新闻资讯 爱范儿(爱范儿 让未来触手可及) 国内聚焦创新和科技领域的第一媒体 钛媒体(钛媒体_引领未来商…

Rust循环和函数

下面聊聊以下主题&#xff1a; 基于条件的分支循环函数属性测试 基于条件的分支 基于条件的分支&#xff0c;可以通过常见的 if、if else 或 if else if else 构造来完成&#xff0c;例如下面的示例&#xff1a; fn main() { let dead false; let health 48; if dead { p…

探索Pyecharts关系图绘制技巧:炫酷效果与创意呈现【第42篇—python:Pyecharts水球图】

文章目录 Pyecharts绘制多种炫酷关系网图引言准备工作代码实战1. 基本关系网图2. 自定义节点样式和边样式3. 关系网图的层级结构4. 添加标签和工具提示5. 动态关系网图6. 高级关系网图 - Les Miserables 示例7. 自定义关系网图布局8. 添加背景图9. 3D 关系网图10. 热力关系网图…

【幻兽帕鲁】开服务器,高性能高带宽(100mbps),免费!!!【学生党强推】

【幻兽帕鲁】开服务器&#xff0c;高性能高带宽&#xff08;100mbps&#xff09;&#xff0c;免费&#xff01;&#xff01;&#xff01;【学生党强推】 教程相关视频地址&#xff1a;https://www.bilibili.com/video/BV16e411Y7Fd/ 目前幻兽帕鲁开服务器有以下几套比较性价比的…

【Android】MediaCodec学习

在开源Android屏幕投屏代码scrcpy中&#xff0c;使用了MediaCodec去获取和display关联的surface的内容&#xff0c;再通过写fd的方式&#xff08;socket等&#xff09;传给PC端&#xff0c; MediaCodec的处理看起来比较清楚&#xff0c;数据in和数据out 这里我们做另外一个尝试…

qml与C++的交互

qml端使用C对象类型、qml端调用C函数/c端调用qml端函数、qml端发信号-连接C端槽函数、C端发信号-连接qml端函数等。 代码资源下载&#xff1a; https://download.csdn.net/download/TianYanRen111/88779433 若无法下载&#xff0c;直接拷贝以下代码测试即可。 main.cpp #incl…

二叉树--199. 二叉树的右视图/medium 理解度C

199. 二叉树的右视图 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出…

FPGA 通过 UDP 以太网传输 JPEG 压缩图片

FPGA 通过 UDP 以太网传输 JPEG 压缩图片 简介 在 FPGA 上实现了 JPEG 压缩和 UDP 以太网传输。从摄像机的输入中获取单个灰度帧&#xff0c;使用 JPEG 标准对其进行压缩&#xff0c;然后通过UDP以太网将其传输到另一个设备&#xff08;例如计算机&#xff09;&#xff0c;所有…

Element-Plus如何实现表单校验和表单重置

一&#xff1a;页面布局介绍&#xff1a; 这是我刚刚用基于vue3element-plus写好的一个部门管理的页面 基本的增删改查已经写好&#xff0c;下面我只提供页面的template和style的代码&#xff1a; template <template><el-card class"box-card"><…

【YOLO系列算法俯视视角下舰船目标检测】

YOLO系列算法俯视视角下舰船目标检测 数据集和模型YOLO系列算法俯视视角下舰船目标检测YOLO系列算法俯视视角下舰船目标检测可视化结果 数据集和模型 数据和模型下载&#xff1a; YOLOv6俯视视角下舰船目标检测训练好的舰船目标检测模型舰船目标检测数据YOLOv7俯视视角下舰船…

贝锐蒲公英全新网页认证,保障企业访客无线网络安全

随着企业规模的不断扩大、人员的增长、无线终端数量/类型的增加&#xff0c;传统WiFi无线网络会暴露出越来越多的问题&#xff0c;导致无线网络管理困难。 比如&#xff1a;采用弱密码、安全防护不到位的默认设置、员工缺乏信息安全意识、未经授人员权访问无线网络…… 这些问…

【Redis】Redis有哪些适合的场景

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a;Redis ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 &#xff08;1&#xff09;会话缓存&#xff08;Session Cache&#xff09; &#xff08;2&#xff09;全页缓存&#xff08;FPC…

【极数系列】Flink配置参数如何获取?(06)

文章目录 gitee码云地址简介概述01 配置值来自.properties文件1.通过路径读取2.通过文件流读取3.通过IO流读取 02 配置值来自命令行03 配置来自系统属性04 注册以及使用全局变量05 Flink获取参数值Demo1.项目结构2.pom.xml文件如下3.配置文件4.项目主类5.运行查看相关日志 gite…

Linux 网络流量相关工具

本文聚焦于网络流量的查看、端口占用查看。至于网络设备的管理和配置&#xff0c;因为太过复杂且不同发行版有较大差异&#xff0c;这里就不赘述&#xff0c;后面看情况再写。 需要注意的是&#xff0c;这里列出的每一个工具都有丰富的功能&#xff0c;流量/端口信息查看只是其…