etcd 快速入门
简介
随着go与kubernetes的大热,etcd作为一个基于go编写的分布式键值存储,逐渐为开发者所熟知,尤其是其还作为kubernetes的数据存储仓库,更是引起广泛专注。
本文我们就来聊一聊etcd到底是什么及其工作机制。
首先,coreos官方是这么定义etcd的:
A highly-available key value store for shared configuration and service discovery(etcd是一个高可用的用于共享配置和服务发现的KV存储)
事实上,etcd是一个受到zookeeper和doozer启发而催生的项目。除了与之拥有类似的功能之外,现专注于如下几点:
- 简单: 基于http+json的api
- 安全: 可选的ssl认证机制
- 快速: 每个实例每秒支持1000次写操作
- 可信: 使用raft算法实现分布式
使用场景
下面是一些etcd较常用的使用场景:
- 服务发现:在微服务的应用场景中,各服务主动向etcd注册自己,并通过etcd获取其依赖的服务的注册信息。
- 配置管理:事实上配置管理使用的就是消息发布与订阅。即构建一个配置共享中心,数据提供者在这个配置中心发布消息,而消息使用者则订阅他们关心的主题,一旦主题有消息发布,就会实时通知订阅者。通过这种方式可以做到分布式系统配置的集中式管理与动态更新。
- 应用调度: 事实上应用调度的功能也是依托于服务的注册与发现。一个服务多个副本都注册至etcd,利用etcd维护一个负载均衡节点表。etcd可以监控一个集群中多个节点的状态,当有一个请求发过来后,可以轮询式的把请求转发给存活着的多个状态。
- 分布式通知与协调:与消息发布和订阅有些相似。都用到了etcd中的Watcher机制,通过注册与异步通知机制,实现分布式环境下不同系统之间的通知与协调,从而对数据变更做到实时处理。与消息发布和订阅不同的是,发布和订阅通常用于获取配置以更新服务。而分布式通知与协调,通常是多个不同的服务监听同一个目录,但其中一个服务修改了该目录,则触发其他服务的相应操作,一个典型的应用场景即通过etcd实现应用的健康检查
- 分布式锁:因为etcd使用raft算法保证了数据的强一致性,某次操作存储至etcd的值必须全局唯一,所以比较容易实现分布式锁
- 分布式队列:与分布式锁的场景类似,可创建一个先进先出队列,保证顺序
- 选主:通过etcd为一些分布式应用选举leader节点
组件说明
架构说明
etcd主要分为四个部分。
HTTP Server: 用于处理用户发送的API请求以及其它etcd节点的同步与心跳信息请求。在最新的版本中也已经支持了grpc
Store:Store 是 Etcd 数据存储的核心部分,它保存了所有的键值对。Store 可以看作是一个内存中的键值数据库,所有的读写操作都会在这个内存结构中进行。Store 是为了提供快速的数据访问而设计的,因为大多数读写操作可以直接从内存中完成。
Raft:Raft强一致性算法的具体实现,是etcd的核心。
WAL:Write Ahead Log(预写式日志),是一种用于持久化数据的技术,它是在内存中的 Store 发生更改之前先将更改记录到磁盘的日志。WAL 的主要目的是为了提高数据的持久性和容错能力。即使在节点突然宕机的情况下,WAL 文件也可以用来恢复内存中的 Store。
通常,一个用户的请求发送过来,会经由HTTP Server转发给Store进行数据的读写操作,如果涉及到节点的修改,则交给Raft模块进行状态的变更、日志的记录,然后再同步给别的etcd节点以确认数据提交,最后进行数据的提交,再次同步。
工作原理
选主
Raft协议是用于维护一组服务节点数据一致性的协议。这一组服务节点构成一个集群,并且有一个主节点来对外提供服务。当集群初始化,或者主节点挂掉后,就需要重新选主。集群中每个节点,任意时刻处于Leader, Follower, Candidate这三个角色之一。选举特点如下:
- 当集群初始化时候,每个节点都是Follower角色;
- 集群中存在至多1个有效的主节点,通过心跳与其他节点同步数据;
- 当Follower在一定时间内没有收到来自主节点的心跳,会将自己角色改变为Candidate,并发起一次选主投票;当收到包括自己在内超过半数节点赞成后,选举成功,自己成为主;当收到票数不足半数选举失败,或者选举超时。若本轮未选出主节点,将进行下一轮选举(出现这种情况,是由于多个节点同时选举,所有节点均未获得过半选票)。
- Candidate节点收到来自主节点的信息后,会立即终止选举过程,进入Follower角色。
- 为了避免陷入选主失败循环,每个节点未收到心跳发起选举的时间是一定范围内的随机值,这样能够避免2个节点同时发起选主。
日志复制
所谓日志复制,是指主节点将每次操作形成日志条目,并持久化到本地磁盘,然后通过网络IO发送给其他节点。其他节点根据日志的逻辑时钟(TERM)和日志编号(INDEX)来判断是否将该日志记录持久化到本地。当主节点收到包括自己在内超过半数节点成功返回,那么认为该日志是可提交的(committed),并将日志输入到状态机,将结果返回给客户端。
这里需要注意的是,每次选主都会形成一个唯一的TERM编号,相当于逻辑时钟。每一条日志都有全局唯一的编号。
主节点通过网络IO向其他节点追加日志。若某节点收到日志追加的消息,首先判断该日志的TERM是否过期,以及该日志条目的INDEX是否比当前以及提交的日志的INDEX跟早。若已过期,或者比提交的日志更早,那么就拒绝追加,并返回该节点当前的已提交的日志的编号。否则,将日志追加,并返回成功。
当主节点收到其他节点关于日志追加的回复后,若发现有拒绝,则根据该节点返回的已提交日志编号,发生其编号下一条日志。
主节点像其他节点同步日志,还作了拥塞控制。具体地说,主节点发现日志复制的目标节点拒绝了某次日志追加消息,将进入日志探测阶段,一条一条发送日志,直到目标节点接受日志,然后进入快速复制阶段,可进行批量日志追加。
按照日志复制的逻辑,我们可以看到,集群中慢节点不影响整个集群的性能。另外一个特点是,数据只从主节点复制到Follower节点,这样大大简化了逻辑流程。
安全性
选主以及日志复制都是为了保证节点间的数据一致性。但是仅仅依靠选主和日志复制并不能完全保证节点间数据一致。比如,当某个节点挂掉了,一段时间后再次重启,并当选为主节点。而在其挂掉这段时间内,集群若有超过半数节点存活,集群会正常工作,那么会有日志提交。这些提交的日志无法传递给挂掉的节点。当挂掉的节点再次当选主节点,它将缺失部分已提交的日志。在这样场景下,按Raft协议,它将自己日志复制给其他节点,会将集群已经提交的日志给覆盖掉。
这显然是不可接受的。
其他协议解决这个问题的办法是,新当选的主节点会询问其他节点,和自己数据对比,确定出集群已提交数据,然后将缺失的数据同步过来。这种方案有明显缺陷,增加了集群恢复服务的时间(集群在选举阶段不可服务),并且增加了协议的复杂度。
Raft的解决办法是,在选主逻辑中,对能够成为主的节点加以限制,确保选出的节点一定包含了集群已经提交的所有日志。如果新选出的主节点已经包含了集群所有提交的日志,那就不需要从和其他节点比对数据了。简化了流程,缩短了集群恢复服务的时间。
这里存在一个问题,加以这样限制之后,还能否选出主呢?答案是:只要仍然有超过半数节点存活,这样的主一定能够选出。因为已经提交的日志必然被集群中超过半数节点持久化,显然前一个主节点提交的最后一条日志也被集群中大部分节点持久化。当主节点挂掉后,集群中仍有大部分节点存活,那这存活的节点中一定存在一个节点包含了已经提交的日志了。
相关术语
- Raft:etcd所采用的保证分布式系统强一致性的算法。
- Node:一个Raft状态机实例。
- Member: 一个etcd实例。它管理着一个Node,并且可以为客户端请求提供服务。
- Cluster:由多个Member构成可以协同工作的etcd集群。
- Peer:对同一个etcd集群中另外一个Member的称呼。
- Client: 向etcd集群发送HTTP请求的客户端。
- WAL:预写式日志,etcd用于持久化存储的日志格式。
- snapshot:etcd防止WAL文件过多而设置的快照,存储etcd数据状态。
- Proxy:etcd的一种模式,为etcd集群提供反向代理服务。
- Leader:Raft算法中通过竞选而产生的处理所有数据提交的节点。
- Follower:竞选失败的节点作为Raft中的从属节点,为算法提供强一致性保证。
- Candidate:当Follower超过一定时间接收不到Leader的心跳时转变为Candidate开始竞选。
- Term:某个节点成为Leader到下一次竞选时间,称为一个Term。
- Index:数据项编号。Raft中通过Term和Index来定位数据。
部署
docker compose 单机部署
首先创建两个文件夹,一个是数据目录,一个是密钥目录
mkdir -p /docker/etcd/data
mkdir /docker/etcd/ca-certificates
进入密钥目录
cd /docker/etcd/ca-certificates
生成 CA 的私钥和证书
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=etcd-ca" -days 10000 -out ca.crt
生成 etcd 服务器的私钥和证书签名请求
openssl genrsa -out etcd.key 2048
openssl req -new -key etcd.key -subj "/CN=etcd-server" -out etcd.csr
使用 CA 证书和私钥签署 etcd 服务器的证书
openssl x509 -req -in etcd.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out etcd.crt -days 10000
生成 etcd 客户端的私钥和证书签名请求
openssl genrsa -out etcdclient.key 2048
openssl req -new -key etcdclient.key -subj "/CN=etcd-client" -out etcdclient.csr
使用 CA 证书和私钥签署 etcd 客户端的证书
openssl x509 -req -in etcdclient.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out etcdclient.crt -days 10000
创建 docker-compose.yml 在 /docker/etcd/ 目录下即可
vim docker-compose.yml
services:etcd:image: bitnami/etcdcontainer_name: etcdrestart: alwaysports:- 4001:4001- 2380:2380- 2379:2379volumes:- /docker/etcd/ca-certificates/:/etc/ssl/certs- /docker/etcd/data:/bitnami/etcd/dataenvironment:- TZ=Asia/Shanghai- ETCD_NAME=etcd0- ETCD_DATA_DIR=/bitnami/etcd/data- ETCD_ROOT_PASSWORD=123456- ETCD_CLIENT_CERT_AUTH=true- ETCD_PEER_CLIENT_CERT_AUTH=true- ETCD_ADVERTISE_CLIENT_URLS=http://192.168.142.157:2379,http://192.168.142.157:4001- ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:2379,http://0.0.0.0:4001- ETCD_INITIAL_ADVERTISE_PEER_URLS=http://192.168.142.157:2380- ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380- ETCD_INITIAL_CLUSTER_TOKEN=etcd-cluster-1- ETCD_INITIAL_CLUSTER=etcd0=http://192.168.142.157:2380- ETCD_INITIAL_CLUSTER_STATE=new- ETCD_CERT_FILE=/etc/ssl/certs/etcd.crt- ETCD_KEY_FILE=/etc/ssl/certs/etcd.key- ETCD_TRUSTED_CA_FILE=/etc/ssl/certs/ca.crt- ETCD_PEER_CERT_FILE=/etc/ssl/certs/etcd.crt- ETCD_PEER_KEY_FILE=/etc/ssl/certs/etcd.key- ETCD_PEER_TRUSTED_CA_FILE=/etc/ssl/certs/ca.crt- ETCD_CLIENT_CERT_AUTH=true
元神启动
docker compose up -d
查看是否启动
root@master:/docker/etcd# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
55ff0118d4be bitnami/etcd "/opt/bitnami/script…" 22 minutes ago Up 22 minutes 0.0.0.0:2379-2380->2379-2380/tcp, :::2379-2380->2379-2380/tcp, 0.0.0.0:4001->4001/tcp, :::4001->4001/tcp etcd
运行
docker exec -it etcd etcdctl --endpoints=http://192.168.142.157:2379 --user=root:123456 get /
在这个过程中我遇到了这个问题
chmod: changing permissions of '/bitnami/etcd/data': Operation not permitted
我是这么解决的:设置权限(实在不行干脆把 /docker/etcd 设置成 777)
chmod 777 /docker/etcd/data -R
现在权限问题解决了之后我又遇到了一个新的问题
root@master:/docker/etcd# docker exec -it etcd etcdctl --endpoints=http://192.168.142.157:2379 --user=root:123456 get /
{"level":"warn","ts":"2024-10-04T23:15:09.800270+0800","logger":"etcd-client","caller":"v3@v3.5.16/retry_interceptor.go:63","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0003501e0/192.168.142.157:2379","attempt":0,"error":"rpc error: code = FailedPrecondition desc = etcdserver: authentication is not enabled"}
这个错误是etcd的认证没有开启
接下来让我们来开启认证
先查看是否开启了认证
docker exec -it etcd etcdctl auth status
结果
Authentication Status: false
AuthRevision: 1
查看用户列表和角色列表
docker exec -it etcd etcdctl role list
docker exec -it etcd etcdctl user list
结果:什么都没有
添加root角色
docker exec -it etcd etcdctl role add root
添加root用户
docker exec -it etcd etcdctl user add root:123456
再次查看用户列表和角色列表
给root用户赋予root角色
docker exec -it etcd etcdctl user grant-role root root
结果:两个都是 root
好了,开启认证看看
docker exec -it etcd etcdctl auth enable
参考:https://blog.csdn.net/HYZX_9987/article/details/135237119
感谢大佬的博客 ^–^
这个时候我就再也没有遇到报错了,让我们来插入数据试试
docker exec -it etcd etcdctl --endpoints=http://192.168.142.157:2379 --user=root:123456 put /mykey "myvalue"
查看插入的数据
etcdctl --endpoints=http://192.168.142.157:2379 --user=root:123456 get /mykey
结果
/mykey
myvalue
至此,单机部署完成
etcd 的简单使用
增
etcdctl put /key "value"
设置带有过期时间的键
etcdctl put /key --ttl 60 "value"
删
etcdctl del /key
查
etcdctl get /key
列出
etcdctl ls /
监控
监控键 key 的变化,如果有更新,会输出变化后的值。
etcdctl watch /key
执行事务
执行一个包含多个操作的事务
etcdctl txn \put /txn_key "value1" \get /txn_key
检查领导选举
使用 etcd 进行领导者选举。
etcdctl elect --ttl 60 --period 5 /myelection mycandidate
获取成员列表
etcdctl member list
获取集群状态
etcdctl endpoint health
相关文章:

etcd 快速入门
简介 随着go与kubernetes的大热,etcd作为一个基于go编写的分布式键值存储,逐渐为开发者所熟知,尤其是其还作为kubernetes的数据存储仓库,更是引起广泛专注。 本文我们就来聊一聊etcd到底是什么及其工作机制。 首先,…...

Spring MVC__HttpMessageConverter、拦截器、异常处理器、注解配置SpringMVC、SpringMVC执行流程
目录 一、HttpMessageConverter1、RequestBody2、RequestEntity3、ResponseBody4、SpringMVC处理json5、SpringMVC处理ajax6、RestController注解7、ResponseEntity7.1、文件下载7.2、文件上传 二、拦截器1、拦截器的配置2、拦截器的三个抽象方法3、多个拦截器的执行顺序 三、异…...

GAMES101(19节,相机)
相机 synthesis合成成像:比如光栅化,光线追踪,相机是capture捕捉成像, 但是在合成渲染时,有时也会模拟捕捉成像方式(包括一些技术 动态模糊 / 景深等),这时会有涉及很多专有名词&a…...

Django Nginx+uwsgi 安装配置
Django Nginx+uwsgi 安装配置 本文将详细介绍如何在Linux环境下安装和配置Django应用程序,使用Nginx作为Web服务器和uwsgi作为应用程序服务器。我们将覆盖以下主题: 安装Python和相关库安装和配置Django安装Nginx安装和配置uwsgi配置Nginx以使用uwsgi测试和调试1. 安装Pytho…...

oracle数据备份和导入
一、数据导出 创建目录对象: CREATE DIRECTORY dpump_dir AS /path/to/your/directory;授予权限: GRANT READ, WRITE ON DIRECTORY dpump_dir TO test_user; #导出的用户导出全库数据 expdp your_user/your_password DIRECTORYdpump_dir DUMPFILEfu…...

C++ | Leetcode C++题解之第452题用最少数量的箭引爆气球
题目: 题解: class Solution { public:int findMinArrowShots(vector<vector<int>>& points) {if (points.empty()) {return 0;}sort(points.begin(), points.end(), [](const vector<int>& u, const vector<int>&…...

react-问卷星项目(3)
项目实战 React Hooks 缓存,性能优化,提升时间效率,但是不要为了技术而优化,应该是为了业务而进行优化 内置Hooks保证基础功能,灵活配合实现业务功能,抽离公共部分,自定义Hooks或者第三方&am…...

69 BERT预训练_by《李沐:动手学深度学习v2》pytorch版
系列文章目录 文章目录 系列文章目录NLP里的迁移学习Bert的动机Bert架构对输入的修改五、预训练任务1、2、3、 六、1、2、3、 七、1、2、3、 八、1、2、3、 NLP里的迁移学习 之前是使用预训练好的模型来抽取词、句子的特征,例如 word2vec 或语言模型这种非深度学习…...

Java报错输出的信息究竟是什么?
Java报错输出的信息究竟是什么? 本篇会带大家了解一下java运行时报错输出的信息内容,简单学习一下虚拟机内存中Java虚拟机栈的工作方式以及栈帧中所存储的信息内容 异常信息 当你的程序运行报错时,你是否会好奇打印出来的那一大坨红色的究竟…...

解表之紫苏
** 声明:本文介绍的中药仅供学习使用,请勿擅自使用,否则后果自负!!!因水平有限,如有不当之处,请批评指正!!!!图片来源网络࿰…...

JavaScript数据类型
目录 JavaScripit数据类型 原始类型(Primitive Types) 1 Undefined 特点 实例 2 Null 实例 3 Boolean 重点: 常用falsy情况: 思考 4 Number,BigInt 实例 特点 NaN 5 String 在JavaScript中表示字符串有三种表示方…...

市场中的新兴力量与未来发展
在当前瞬息万变的全球金融市场中,期货交易以其高杠杆与灵活性,吸引了越来越多的投资者参与其中。大粤期货作为中国期货行业的新兴力量,凭借其创新的交易平台、广泛的产品线及专业的风险管理服务,迅速在市场中崭露头角。本文将介绍…...

Golang | Leetcode Golang题解之第446题等差数列划分II-子序列
题目: 题解: func numberOfArithmeticSlices(nums []int) (ans int) {f : make([]map[int]int, len(nums))for i, x : range nums {f[i] map[int]int{}for j, y : range nums[:i] {d : x - ycnt : f[j][d]ans cntf[i][d] cnt 1}}return }...

Java 常用序列化对比
Java 中常用的序列化方式主要包括以下几种: 1. Java 原生序列化 使用方式: 使用 java.io.Serializable 接口。对象需要实现该接口,然后通过 ObjectOutputStream 和 ObjectInputStream 进行序列化和反序列化。 示例代码: import java.io.*;public class Person impleme…...

【redis学习篇1】redis基本常用命令
目录 redis存储数据的模式 常用基本命令 一、set 二、keys pattern keys 字符串当中携带问号 keys 字符串当中携带*号 keys 【^字母】 keys * 三、exists 四、del 五、expire 5.1 ttl命令 5.2key删除策略 5.2.1惰性删除 5.2.2定期删除 六、type key的数据类型…...

量子计算:颠覆未来计算的革命性技术
量子计算:颠覆未来计算的革命性技术 量子计算作为下一代颠覆性技术,正在引领计算领域的重大变革。与传统计算机基于比特的二进制运算不同,量子计算通过量子比特(qubits)在叠加态和纠缠态下实现并行计算,能…...

ctfshow-web入门(信息收集,持续更新中。。)
写在之前:近期打了个比赛,备受打击,入手了vip账号进修,加油! 文章目录 ctfshow-web1查看源代码ctfshow-web2burp抓包ctfshow-web3burp抓包ctfshow-web4访问robots.txtctfshow-web5dirscarch扫描PHPS文件泄露ctfshow-web6dirscarch扫描ctfshow-web7dirscarch扫描ctfshow-w…...

蓝桥杯【物联网】零基础到国奖之路:十五. 扩展模块之双路ADC
蓝桥杯【物联网】零基础到国奖之路:十五. 扩展模块之双路ADC 第一节 硬件解读第二节 CubeMX配置第三节 代码编写 第一节 硬件解读 STM32的ADC是12位,通过硬件过采样扩展到16位,模数转换器嵌入到STM32L071xx器件中。有16个外部通道和2个内部通道…...

李飞飞谈AI+3D发展:3D/4D AI将成为下一个重要前沿
人工智能(AI)的发展已经深刻改变了我们的世界,从简单的图像识别到复杂的自然语言处理,再到如今正在兴起的生成式模型。在这个过程中,李飞飞教授认为,3D/4D AI技术将是推动下一波变革的关键力量。以下根据她的观点整理了AI发展历程中的关键里程碑以及对3D/4D AI未来发展的…...

centos72009源码编译R语言
./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Pconnect -Psparkr -Phive -Phive-thriftserver -Pmesos -Pyarn -Dhadoop.version3.4.0 -Pkubernetes spark3.5.3 源码版本 ./dev/make-distribution.sh --name custom-spark --pip --r --tgz -Pconnect -P…...

初识算法 · 双指针(4)
目录 前言: 复写零 题目解析 算法原理 算法编写 四数之和 题目解析 算法原理 算法编写 前言: 本文是双指针算法的最后一文,以复写零和四数之和作为结束,介绍方式同样是题目解析,算法原理,算法编写…...

java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码
java版鸿鹄电子招投标系统功能架构设计 核心功能设计 鸿鹄电子招投标采购系统源码...

matlab 判断多组数据的分布是否一致,可以使用什么方法?
在 MATLAB 中,可以使用以下几种方法来判断多组数据的分布是否一致: 1. Kolmogorov-Smirnov 检验 (K-S Test) K-S 检验是一种非参数检验,用于比较两组数据是否来自相同的分布。MATLAB 提供了 kstest2 函数来进行这种检验。该方法适用于连续分…...

jenkins配置eureka、nacos发布优雅上下线服务
eureka发布期间优雅上下线 1、编写eureka下线脚本 vim biz_out_of_service-eureka.pyimport sys import requests#服务名,脚本第一个参数 APP_NAMEsys.argv[1] # 需要置为OUT_OF_SERVICE的服务实例的ID,脚本第二个参数 INSTANCE_IDsys.argv[2]# Eureka…...

【JAVA开源】基于Vue和SpringBoot的周边产品销售网站
本文项目编号 T 061 ,文末自助获取源码 \color{red}{T061,文末自助获取源码} T061,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...

【C++差分数组】2381. 字母移位 II|1793
本文涉及知识点 C差分数组 LeetCode2381. 字母移位 II 给你一个小写英文字母组成的字符串 s 和一个二维整数数组 shifts ,其中 shifts[i] [starti, endi, directioni] 。对于每个 i ,将 s 中从下标 starti 到下标 endi (两者都包含&#…...

【pytorch】范数的计算
近日在看沐神的《动手学深度学习》,其中提到了范数这一数学概念,感觉很陌生,参考ChatGPT补一下知识。 目录 范数示例 1: 计算向量的 L2 范数(欧几里得范数)示例 2: 计算矩阵的 Frobenius 范数示例 3: 计算向量的 L1 范数(曼哈顿距离)曼哈顿范数的定义曼哈顿范数的计算示…...

MATLAB|基于多主体主从博弈的区域综合能源系统低碳经济优化调度
目录 主要内容 程序亮点: 模型研究 一、综合能源模型 二、主从博弈框架 部分代码 结果一览 下载链接 主要内容 程序参考文献《基于多主体主从博弈的区域综合能源系统低碳经济优化调度》,采用了区域综合能源系统多主体博弈协同优化方…...

Django 后端数据传给前端
Step 1 创建一个数据库 Step 2 在Django中点击数据库连接 Step 3 连接成功 Step 4 settings中找DATABASES Step 5 将数据库挂上面 将数据库引擎和数据库名改成自己的 Step 6 在_init_.py中加上数据库的支持语句 import pymysql pymysql.install_as_MySQLdb() Step7 简单创建两…...

elasticsearch 写入新数据测试(二)
背景:elasticsearch单个node节点写入数据-CSDN博客 需要设置密码才能作为外部调用,不设置我不会用。设置方法见上一篇。 设置密码出现如下问题: Unexpected response code [503] from calling PUT http://172.19.0.1:9200/_security/user/apm_system/_password?pretty …...