Zookeeper详解(一)——基础介绍

news2024/11/16 0:00:22

概念

zookeeper官网:https://zookeeper.apache.org/

大数据生态系统里的很多组件的命名都是某种动物或者昆虫,比如hadoop就是 🐘,hive就是🐝。zookeeper即动物园管理者,顾名思义就是管理大数据生态系统各组件的管理员,如下图所示:

在这里插入图片描述

zooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务。

  1. 高性能

    zooKeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景。

  2. 高可用

    zooKeeper一般以集群的方式对外提供服务,一般3 ~ 5台机器就可以组成一个可用的zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,并且每台机器之间都相互保持着通信。只要集群中超过一半的机器都能够正常工作,那么整个集群就能够正常对外服务。

  3. 严格顺序访问

    对于来自客户端的每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号,这个编号反映了所有事务操作的先后顺序。

应用场景

ZooKeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调存储服务。

  • 注册中心
  • 配置中心
  • 集群管理
  • 分布式锁
  • 生成分布式唯一ID
  1. 维护配置信息

    zooKeeper、config、nacos都可以当做配置中心使用。分布式兴起,许多服务使用相同的配置文件,如果配置文件发送变化,运维上需要逐个修改服务的配置文件,繁琐。通常会将配置文件部署在一个集群上,提供服务,高效快速且可靠地完成配置项的更改等操作,并能够保证各配置项在每台服务器上的数据一致性。

    zookeeper就可以提供这样一种服务,其使用Zab这种一致性协议来保证一致性。现在有很多开源项目使用zookeeper来维护配置,比如在hbase中,客户端就是连接 一个zookeeper,获得必要的hbase集群的配置信息,然后才可以进一步操作。还有在开源的消息队列kafka中,也使用zookeeper来维护broker的信息。在alibaba开源的soa框架dubbo中也广泛的使用zookeeper管理一些配置来实现服务治理。

在这里插入图片描述

  1. 集群管理&注册中心

    一个集群有时会因为各种软硬件故障或者网络故障,出现某些服务器挂掉而被移除集群,而某些服务器加入到集群中的情况,zookeeper会将这些服务器加入/移出的情况 通知给集群中的其他正常工作的服务器,以及及时调整存储和计算等任务的分配和执行等。此外zookeeper还会对故障的服务器做出诊断并尝试修复。

在这里插入图片描述

  1. 分布式锁

    多台服务器上运行着同一种服务,要协调各服务的进度,有时候需要保证当某个服务在进行某个操作时,其他的服务都不能进行该操作,即对该操作进行加锁,如果当前机器挂掉后,释放锁并fail over 到其他的机器继续执行该服务。

在这里插入图片描述

  1. 生成分布式唯一ID

    单库单表型系统中,通常可以使用数据库字段自带的auto_increment属性来自动为每条记录生成一个唯一的ID。但是分库分表后,就无法在依靠数据库的 auto_increment属性来唯一标识一条记录了。此时我们就可以用zookeeper在分布式环境下生成全局唯一ID。做法如下:每次要生成一个新Id时,创建一个持久顺序节点,创建操作返回的节点序号,即为新Id,然后把比自己节点小的删除即可。

数据模型

zookeeper的数据节点可以视为树状结构(或者目录),树中的各节点被称为znode(即zookeeper node),类似Linux的文件系统,一个znode可以有多个子节点。zookeeper节点在结构上表现为树状;使用路径path来定位某个znode,比如/ns-1/itcast/mysql/schema1/table1,此处ns-1、itcast、mysql、schema1、table1分别是根节点、2级节点、3级节点以及4级节点;其中ns-1是itcast的父节点,itcast是ns-1的子节点,itcast是mysql的父节点,mysql是itcast的子节点,以此类推。

znode,兼具文件和目录两种特点。既像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分。

在这里插入图片描述

znode节点

  • 节点的数据:即znode data(节点path, 节点data)的关系就像是java map中(key, value)的关系

  • 节点的子节点children

  • 节点的状态stat:用来描述当前节点的创建、修改记录,包括cZxid、ctime等

节点状态stat的属性:

在zookeeper shell中使用get命令查看指定路径节点的data、stat信息:

[zk: localhost:2181(CONNECTED) 7] get /ns-1/tenant 

cZxid = 0x6a0000000a 
ctime = Wed Mar 27 09:56:44 CST 2019 
mZxid = 0x6a0000000a 
mtime = Wed Mar 27 09:56:44 CST 2019
pZxid = 0x6a0000000e 
cversion = 2 
dataVersion = 0 
aclVersion = 0 
ephemeralOwner = 0x0 
dataLength = 0 
numChildren = 2

属性说明:

  • cZxid:数据节点创建时的事务 ID ,增删改才有事务 ID
  • ctime:数据节点创建时的时间
  • mZxid:数据节点最后一次更新时的事务 ID
  • mtime:数据节点最后一次更新时的时间
  • pZxid:数据节点的子节点最后一次被修改时的事务 ID
  • cversion:子节点的更改次数
  • dataVersion:节点数据的更改次数
  • aclVersion:节点的 ACL 的更改次数
  • ephemeralOwner:如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为 0
  • dataLength:数据内容的长度
  • numChildren:数据节点当前的子节点个数

节点类型:

zookeeper中的节点有两种,分别为临时节点和永久节点。节点的类型在创建时即被确定,并且不能改变。

临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话(Session)结束,临时节点将被自动删除,当然也可以手动删除。虽然每个临时的Znode都会绑定到一个客户端会话,但他们对所有的客户端还是可见的。另外,ZooKeeper的临时节点不允许拥有子节点。

持久化节点:该节点的生命周期不依赖于会话,并且只有在客户端显示执行删除操作的时候,他们才能被删除。

单机安装

zookeeper底层依赖于jdk,需要提前安装java环境

Windows直接下载,bin/zkServer.cmd启动

Linux使用zookeeper-3.4.10.tar.gz,上传并解压,bin/zkServer.sh启动

// 解压zookeeper 
tar -xzvf zookeeper-3.4.10.tar.gz

// 为zookeeper准备配置文件
// 进入conf目录 
cd /home/zookeeper/zookeeper-3.4.10/conf 
// 复制配置文件 
cp zoo_sample.cfg zoo.cfg 
// zookeeper根目录下新建data目录 
mkdir data 
// vi 修改配置文件中的dataDir 
vi zoo.cfg 
// 此路径用于存储zookeeper中数据的内存快照、及事物日志文件 dataDir=/home/zookeeper/zookeeper-3.4.10/data

// 启动zookeeper
// 进入zookeeper的bin目录 
cd /home/zookeeper/zookeeper-3.4.10/bin 

// 启动zookeeper 
./zkServer.sh start 

//启动:zkServer.sh start 
//停止:zkServer.sh stop 
//查看状态:zkServer.sh status

// 进入Shell命令窗口
./zkCli.sh

常用Shell命令

新增节点

create [-s] [-e] path data #其中-s为有序节点,-e临时节点,默认持久化节点

#创建持久化节点并写入数据:
create /hadoop "123456"
get /hadoop

#创建持久化有序节点,此时创建的节点名为指定节点名 + 自增序号/a0000000000
[zk: localhost:2181(CONNECTED) 2] create -s /a "aaa" 
Created /a0000000000 
[zk: localhost:2181(CONNECTED) 3] create -s /b "bbb" 
Created /b0000000001 
[zk: localhost:2181(CONNECTED) 4] create -s /c "ccc" 
Created /c0000000002

get /a0000000000 / get /a

#创建临时节点,临时节点会在会话过期后被删除
[zk: localhost:2181(CONNECTED) 5] create -e /tmp "tmp" 
Created /tmp

#创建临时有序节点,临时节点会在会话过期后被删除
[zk: localhost:2181(CONNECTED) 6] create -s -e /aa 'aaa' 
Created /aa0000000004 
[zk: localhost:2181(CONNECTED) 7] create -s -e /bb 'bbb' 
Created /bb0000000005 
[zk: localhost:2181(CONNECTED) 8] create -s -e /cc 'ccc' 
Created /cc0000000006

更新节点

#更新节点的命令是 set ,可以直接进行修改,如下:
[zk: localhost:2181(CONNECTED) 3] set /hadoop "345" 
cZxid = 0x4 
ctime = Thu Dec 12 14:55:53 CST 2019 
mZxid = 0x5 
mtime = Thu Dec 12 15:01:59 CST 2019 
pZxid = 0x4 
cversion = 0 
dataVersion = 1 
aclVersion = 0 
ephemeralOwner = 0x0 
dataLength = 3 
numChildren = 0

#也可以基于版本号进行更改,此时类似于乐观锁机制,当你传入的数据版本号 (dataVersion) 和当前节点的数据版本号不符合时,zookeeper 会拒绝本次修改:
[zk: localhost:2181(CONNECTED) 10] set /hadoop "3456" 1 
version No is not valid : /hadoop

删除节点

#删除节点的语法如下:
delete path [version]

#和更新节点数据一样,也可以传入版本号,当你传入的数据版本号 (dataVersion) 和当前节点的数据版本号不符合时,zookeeper 不会执行删除操作。
[zk: localhost:2181(CONNECTED) 36] delete /hadoop 0 
version No is not valid : /hadoop #无效的版本号 
[zk: localhost:2181(CONNECTED) 37] delete /hadoop 1 
[zk: localhost:2181(CONNECTED) 38]

#要想删除某个节点及其所有后代节点,可以使用递归删除,命令为 rmr path

查看节点

get path

[zk: localhost:2181(CONNECTED) 1] get /hadoop 
123456 
cZxid = 0x4
ctime = Thu Dec 12 14:55:53 CST 2019
mZxid = 0x4 
mtime = Thu Dec 12 14:55:53 CST 2019 
pZxid = 0x4 
cversion = 0 
dataVersion = 0 
aclVersion = 0 
ephemeralOwner = 0x0 
dataLength = 6 
numChildren = 0

节点各个属性如下表。其中一个重要的概念是 Zxid(ZooKeeper Transaction Id),ZooKeeper 节点的每一次更改都具有唯一的 Zxid,如果 Zxid1 小于 Zxid2,则Zxid1 的更改发生在 Zxid2 更改之前。

状态属性说明
cZxid数据节点创建时的事务 ID
ctime数据节点创建时的时间
mZxid数据节点最后一次更新时的事务 ID
mtime数据节点最后一次更新时的时间
pZxid数据节点的子节点最后一次被修改时的事务 ID
cversion子节点的更改次数
dataVersion节点数据的更改次数
aclVersion节点的 ACL 的更改次数
ephemeralOwner如果节点是临时节点,则表示创建该节点的会话的SessionID;如果节点是持久节点,则该属性值为 0
dataLength数据内容的长度
numChildren数据节点当前的子节点个数

查看节点状态

#可以使用 stat 命令查看节点状态,它的返回值和 get 命令类似,但不会返回节点数据
[zk: localhost:2181(CONNECTED) 2] stat /hadoop 
cZxid = 0x4 
ctime = Thu Dec 12 14:55:53 CST 2019 
mZxid = 0x4 
mtime = Thu Dec 12 14:55:53 CST 2019 
pZxid = 0x4 
cversion = 0 
dataVersion = 0 
aclVersion = 0 
ephemeralOwner = 0x0 
dataLength = 6 
numChildren = 0

查看节点列表

#查看节点列表有 ls path 和 ls2 path 两个命令,后者是前者的增强,不仅可 以查看指定路径下的所有节点,还可以查看当前节点的信息
[zk: localhost:2181(CONNECTED) 0] ls / 
[cluster, controller_epoch, brokers, storm, zookeeper, admin, ...] 
[zk: localhost:2181(CONNECTED) 1] ls2 / 
[cluster, controller_epoch, brokers, storm, zookeeper, admin, ....] 
cZxid = 0x0 
ctime = Thu Jan 01 08:00:00 CST 1970 
mZxid = 0x0 
mtime = Thu Jan 01 08:00:00 CST 1970 
pZxid = 0x130 
cversion = 19 
dataVersion = 0 
aclVersion = 0 
ephemeralOwner = 0x0 
dataLength = 0 
numChildren = 11

监听器get path [watch]

#使用 get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客户端发出通知。需要注意的是 zookeeper的触发器是一次性的 (One-time trigger),即触发一次后就会立即失效。

#客户端1,监听/hadoop
[zk: localhost:2181(CONNECTED) 4] get /hadoop watch 
#客户端2修改/hadoop,节点值改变,监听到修改事件
WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop

#客户端2
[zk: localhost:2181(CONNECTED) 5] set /hadoop 45678 

监听器stat path [watch]

#使用 stat path [watch] 注册的监听器能够在节点状态发生改变的时候,向客户端发出通知
#客户端1,监听/hadoop
[zk: localhost:2181(CONNECTED) 7] stat /hadoop watch 
#客户端2修改/hadoop,节点值改变,监听到修改事件
WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop #节点值改变

#客户端2
[zk: localhost:2181(CONNECTED) 8] set /hadoop 112233 

监听器ls\ls2 path [watch]

#使用 ls path [watch] 或 ls2 path [watch] 注册的监听器能够监听该节点下 所有子节点的增加和删除操作。
[zk: localhost:2181(CONNECTED) 9] ls /hadoop 
watch []
[zk: localhost:2181(CONNECTED) 10] create /hadoop/yarn "aaa" 
WATCHER:: WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/hadoop

acl权限控制

zookeeper 类似文件系统,client 可以创建节点、更新节点、删除节点,那么如何做到节点的权限的控制呢?zookeeper的access control list 访问控制列表可以做到这一点。

acl 权限控制,使用scheme:id:permission 来标识,主要涵盖 3 个方面:

  • 权限模式(scheme):授权的策略
  • 授权对象(id):授权的对象
  • 权限(permission):授予的权限

其特性如下:

  • zooKeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限
  • 每个znode支持设置多种权限控制方案和多个权限
  • 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

例如:

setAcl /test2 ip:192.168.60.130:crwda 
// 将节点权限设置为Ip:192.168.60.130的客户端可以对节点进行增、删、改、查、管理权限

权限模式

采用何种方式授权

方案描述
world只有一个用户:anyone,代表登录zookeeper所有人(默认)
ip对客户端使用IP地址认证
auth使用已添加认证的用户认证
digest使用“用户名:密码”方式认证,密文

授权对象

给谁授予权限

授权对象ID是指,权限赋予的实体,例如:IP 地址或用户。

授予权限

授予什么权限

create、delete、read、writer、admin也就是 增、删、改、查、管理权限

这5种权限简写为cdrwa,注意:这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

权限ACL简写描述
createc可以创建子节点
deleted可以删除子节点(仅下一级节点)
readr可以读取节点数据及显示子节点列表
writew可以设置节点数据
admina可以设置节点访问控制列表权限

授权的相关命令

命令使用方式描述
getAclgetAcl 读取ACL权限
setAclsetAcl 设置ACL权限
addauthaddauth添加认证用户

案例:

  • world授权模式

    #命令
    setAcl <path> world:anyone:<acl>
    
    #例子
    [zk: localhost:2181(CONNECTED) 1] create /node1 "node1" 
    Created /node1 
    #查看权限
    [zk: localhost:2181(CONNECTED) 2] getAcl /node1 
    'world,'anyone    #world方式对所有用户进行授权 
    : cdrwa    #具有增、删、改、查、管理 
    
    #world方式对所有用户进行授权 
    #增、删、改、查、管理 
    [zk: localhost:2181(CONNECTED) 3] setAcl /node1 world:anyone:cdrwa
    cZxid = 0x2 
    ctime = Fri Dec 13 22:25:24 CST 2019 
    mZxid = 0x2 
    mtime = Fri Dec 13 22:25:24 CST 2019 
    pZxid = 0x2 
    cversion = 0 
    dataVersion = 0 
    aclVersion = 1 
    ephemeralOwner = 0x0 
    dataLength = 5 
    numChildren = 0
    
  • IP授权模式

    #命令
    setAcl <path> ip:<ip>:<acl>
    
    注意:远程登录zookeeper命令:./zkCli.sh -server ip
    
    #例子
    [zk: localhost:2181(CONNECTED) 18] create /node2 "node2" 
    Created /node2 
    
    #设置权限
    [zk: localhost:2181(CONNECTED) 23] setAcl /node2 ip:192.168.60.129:cdrwa 
    cZxid = 0xe 
    ctime = Fri Dec 13 22:30:29 CST 2019 
    mZxid = 0x10 
    mtime = Fri Dec 13 22:33:36 CST 2019 
    pZxid = 0xe 
    cversion = 0 
    dataVersion = 2 
    aclVersion = 1 
    ephemeralOwner = 0x0 
    dataLength = 20 
    numChildren = 0 
    
    [zk: localhost:2181(CONNECTED) 25] getAcl /node2 
    'ip,'192.168.60.129 
    :cdrwa 
    
    #使用IP非192.168.60.129 的机器 
    [zk: localhost:2181(CONNECTED) 0] get /node2 
    Authentication is not valid : /node2 #没有权限
    
    #设置多个ip对同一个node的权限
    setAcl /node2 ip:192.168.60.129:cdrwa,ip:192.168.60.130:cdrwa
    
  • Auth授权模式

    #命令
    addauth digest <user>:<password> #添加认证用户 
    setAcl <path> auth:<user>:<acl>
    
    #例子
    [zk: localhost:2181(CONNECTED) 2] create /node3 "node3" 
    Created /node3 
    
    #添加认证用户 
    [zk: localhost:2181(CONNECTED) 4] addauth digest itcast:123456 
    [zk: localhost:2181(CONNECTED) 1] setAcl /node3 auth:itcast:cdrwa 
    cZxid = 0x15 
    ctime = Fri Dec 13 22:41:04 CST 2019 
    mZxid = 0x15 
    mtime = Fri Dec 13 22:41:04 CST 2019 
    pZxid = 0x15 
    cversion = 0 
    dataVersion = 0 
    aclVersion = 1 
    ephemeralOwner = 0x0 
    dataLength = 5 
    numChildren = 0 
    
    [zk: localhost:2181(CONNECTED) 0] getAcl /node3 'digest,'itcast:673OfZhUE8JEFMcu0l64qI8e5ek= 
    : cdrwa 
    
    #添加认证用户后可以访问 
    [zk: localhost:2181(CONNECTED) 3] get /node3 node3
    cZxid = 0x15 
    ctime = Fri Dec 13 22:41:04 CST 2019 
    mZxid = 0x15
    mtime = Fri Dec 13 22:41:04 CST 2019 
    pZxid = 0x15
    cversion = 0 
    dataVersion = 0 
    aclVersion = 1 
    ephemeralOwner = 0x0 
    dataLength = 5
    numChildren = 0
    
  • Digest授权模式

    dai j s

    #命令
    setAcl <path> digest:<user>:<password>:<acl>
    
    #这里的密码是经过SHA1及BASE64处理的密文,在SHELL中可以通过以下命令计算:
    echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
    
    #先来计算一个密文
    echo -n itheima:123456 | openssl dgst -binary -sha1 | openssl base64
    qlzQzCLKhBROghkooLvb+Mlwv4A=
    
    #例子
    [zk: localhost:2181(CONNECTED) 4] create /node4 "node4" 
    Created /node4 
    
    #使用是上面算好的密文密码添加权限: 
    [zk: localhost:2181(CONNECTED) 5] setAcl /node4 digest:itheima:qlzQzCLKhBROghkooLvb+Mlwv4A=:cdrwa 
    cZxid = 0x1c 
    ctime = Fri Dec 13 22:52:21 CST 2019 
    mZxid = 0x1c 
    mtime = Fri Dec 13 22:52:21 CST 2019 
    pZxid = 0x1c
    cversion = 0 
    dataVersion = 0 
    aclVersion = 1 
    ephemeralOwner = 0x0 
    dataLength = 5
    numChildren = 0
    
    [zk: localhost:2181(CONNECTED) 6] getAcl /node4 'digest,'itheima:qlzQzCLKhBROghkooLvb+Mlwv4A=
    : cdrwa 
    
    [zk: localhost:2181(CONNECTED) 3] get /node4 
    Authentication is not valid : /node4 #没有权限 
    
    [zk: localhost:2181(CONNECTED) 4] addauth digest itheima:123456 #添加认证用户
    
    [zk: localhost:2181(CONNECTED) 5] get /node4
    1  #成功读取数据
    cZxid = 0x1c 
    ctime = Fri Dec 13 22:52:21 CST 2019 
    mZxid = 0x1c 
    mtime = Fri Dec 13 22:52:21 CST 2019 
    pZxid = 0x1c 
    cversion = 0 
    dataVersion = 0 
    aclVersion = 1 
    ephemeralOwner = 0x0
    dataLength = 5
    numChildren = 0
    
  • 多种模式授权

    同一个节点可以同时使用多种模式授权

    [zk: localhost:2181(CONNECTED) 0] create /node5 "node5" 
    Created /node5 
    
    #添加认证用户
    [zk: localhost:2181(CONNECTED) 1] addauth digest itcast:123456 
    
    #多种模式授权
    [zk: localhost:2181(CONNECTED) 2] setAcl /node5 ip:192.168.60.129:cdra,auth:itcast:cdrwa,digest:itheima:qlzQzCLKhBROgh kooLvb+Mlwv4A=:cdrwa
    

acl超级管理员

zookeeper的权限管理模式有一种叫做super,该模式提供一个超管可以方便的访问任何权限的节点

假设这个超管是:super:admin,需要先为超管生成密码的密文

#linux
echo -n super:admin | openssl dgst -binary -sha1 | openssl base64

那么打开zookeeper目录下的/bin/zkServer.sh服务器脚本文件,找到如下一行:

nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"

这就是脚本中启动zookeeper的命令,默认只有以上两个配置项,我们需要加一个 超管的配置项

"-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv st5y6rkB6HQs="

加完如下:

nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "- Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "- Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv st5y6rkB6HQs="

/ -cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 2>&1 < /dev/null &

之后启动zookeeper,输入如下命令添加权限

addauth digest super:admin #添加认证用户

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux 系统调用的本质

简单概念 fd #include <unistd.h> #include <string.h>int main(int argc,char* argv[]) {char buf[20]{0};read(0,buf,15);write(1,buf,strlen(buf));return 0; }如果想查看某个系统编程的接口&#xff0c;比如想查看 open 函数的用法&#xff0c;可以这样操作…

Python调用C++代码用法——Linux

目录 前言 C/C动态共享库编译 ctype模块 ctype数据类型 使用案例 float数据 指针 结构体及结构体指针 numpy图像当作指针传入 参考资料&#xff1a; 前言 在项目开发中&#xff0c;有时会使用到多种编程语言&#xff0c;比如部分功能是C/C代码实现的&#xff0c;而另一…

《机器学习与应用》实验二:BP神经网络实验

文章目录 一、实验目的二、实验原理BP算法的数学描述三、程序四、实验结论一、实验目的 1、 熟悉MATLAB中神经网络工具箱的使用方法; 2、 通过在MATLAB下面编程实现BP网络逼近标准正弦函数,来加深对BP网络的了解和认识,理解信号的正向传播和误差的反向传递过程。 二、实验…

SAP MM物料与客户主数据的税分类

一&#xff0e;说明 在物料主数据、客户主数据中均有税分类的维护&#xff0c;税分类既不是税码也不代表税率&#xff0c;它们的作用是通过税务条件记录确定税码。所有的税分类在主数据中都是与国家相关的无组织机构数据&#xff0c;例如物料的销售组织有中国&#xff08;ZH&am…

智慧WMS立体仓库管理系统源码 基于springboot框架(已经测试完整带部署搭建教程)源码分享!

淘源码&#xff1a;国内知名的高品质源码免费下载平台 分享一套智慧WMS立体仓库管理系统源码&#xff0c;基于springboot框架 已经测试完整带部署搭建教程。&#xff08;MF00767&#xff09; 需要源码学习可私信我获取。 技术架构 技术框架&#xff1a;SpringBoot layui H…

ESLint插件的使用

官网地址 规范写代码的工具. 多人开发不同规则,提交代码一堆冲突 培养代码风格使用 vscode更改tab缩进空格数----设置—搜索tabsize—找到tab size—修改2(每次按下tab都缩进俩空格)—Vetur > Format Options: Tab Size这个也要修改为2 vscode搜索format----勾选Editor: Fo…

javaweb01--mysql的介绍和增删改查操作

文章目录Mysql的介绍和增删改查说明1. mysql的登陆和退出11 登陆1.2 退出2. SQL语法的简单介绍2.1 语法2.2 SQL分类3. SQL主要操作语句3.1 DDL:操作数据库3.1.1 查询3.1.2 创建数据库3.1.3 删除数据库3.1.4 使用数据库3.2 DDL:操作表3.2.1 查询表3.2.2 创建表3.2.3 数据类型3.2…

《梁启超家书》笔记二——一个人若是在舒服的环境中会消磨志气,那么在困苦懊丧的环境中也一定会消磨志气

目录 一、做事的态度 二、学习与未来 三、发挥其个性之特长&#xff0c;以靖献于社会 四、鼓励相信孩子 五、犯错 六、身体健康 七、做事 八、与费用相关 九、在困苦中求快活 十、让孩子自由决策与建议 十一、处事态度&#xff1a;不要悲观 十二、时事分析 一、做事…

在IDEA中获取文件绝对路径(通用方式)

package com.javase.reflect;/*** 关于文件路径问题* 以前我们都是在IDEA中&#xff0c;依据IDEA默认的当前路径&#xff1a;project的根来获取文件&#xff0c;但是这种方法有它的局限性&#xff0c;那就是当代码离开了IDEA* 换到了其他位置&#xff0c;我们就找不到文…

基于 Tensorflow 2.x 使用 MobileNetV2 微调模型优化训练花卉图像识别模型

一、模型微调 上篇文章我们通过搭建三层卷积模型&#xff0c;训练了花卉图像识别模型&#xff0c;最后经验证集验证后准确率大约为 75% &#xff0c;本篇文章对该数据集进行优化&#xff0c;提高识别的准确度。本篇文章中对于数据集的读取强化不做过多的介绍了&#xff0c;大家…

免拆机,Kindle固件版本5.10.3~5.13.3如何越狱?简单、易操作版

前言 之前有出过Kindle的越狱教程&#xff1a; 无需拆机&#xff0c;Kindle 全系列 5.12.2.2 ~ 5.14.2版本如何越狱&#xff1f;如何安装第三方插件 确实可以越狱&#xff0c;使用的漏洞也是&#xff1a; KindleDrip — From Your Kindle’s Email Address to Using Your C…

ubuntu18.04下mysql数据库C语言API封装

mysql C语言API操作数据库比较繁琐&#xff0c;可以将其封装起来&#xff0c;这样使用比较方便&#xff0c;下面是一种封装方式。 目录 1.连接封装 2.连接池封装 3.测试代码 1.连接封装 将数据库连接进行封装&#xff0c;主要提供如下接口&#xff1a; &#xff08;1&…

L2-030 冰岛人

2018年世界杯&#xff0c;冰岛队因1:1平了强大的阿根廷队而一战成名。好事者发现冰岛人的名字后面似乎都有个“松”&#xff08;son&#xff09;&#xff0c;于是有网友科普如下&#xff1a; 冰岛人沿用的是维京人古老的父系姓制&#xff0c;孩子的姓等于父亲的名加后缀&#x…

torchnet.meter使用教程

前言 最近项目开发过程中遇到了torchnet.metertorchnet.metertorchnet.meter来记录模型信息&#xff0c;搜了好多篇博客潦潦草草&#xff0c;没有一点干货&#xff0c;于是根据官方代码和官方文档&#xff0c;基于自己的理解&#xff0c;制定了使用教程: torchnet简介 torch…

一句话实现报表生成PDF同时通过outlook发送

元旦节快乐 哈喽&#xff0c;大家2023年好呀&#xff01; 今天&#xff0c;元旦最后一天&#xff0c;给大家分享什么好玩的示例呢&#xff1f; 让我来想想&#xff0c;嗯&#xff1f;这样可以吗&#xff1f;一句话就实现将报表生成PDF&#xff0c;同时可以编辑一些信息并通过…

【源码分享】java多用户B2B2C商城源码带WAP手机端源码

分享一款非常不错的java多用户B2B2C商城源码&#xff0c;带WAP手机端源码&#xff0c;源码地址在文末。 需要源码学习&#xff0c;可私信我获取。 一、技术构架&#xff1a; 开发语言&#xff1a; Java1.7 数 据 库 &#xff1a; MySQL5.5 数据库持久层&#xff1a;阿里巴巴…

车载诊断协议UDS——会话模式状态机Session

UDS之Session服务 会话模式管控是汽车电子诊断范畴很重要的两个状态机之一(另一个是安全访问),不同的会话模式是用来区分诊断服务执行权限。 一位非常尊敬的业内前辈曾举如下例子来形容这个状态机:不同的场景,喝对应的酒! 公司商务场合下,对应的酒是红酒;长辈酒桌上,对…

Redis 哨兵模式

哨兵是一个分布式系统&#xff0c;你可以在一个架构中运行多个哨兵进程&#xff0c;这些进程使用流言协议来接收关于Master主服务器是否下线的信息&#xff0c;并使用投票协议来决定是否执行自动故障迁移&#xff0c;以及选择哪个Slave作为新的Master。 一、哨兵模式概述 1.1…

ubuntu做系统常见出错处理方法1

1.不能分区解决办法&#xff08;安装ubuntu没有出现安装选项&#xff0c;也就是找不到硬盘分区怎么办?-爱码网&#xff09; 解决办法是进入bios模式(一般都是重启时反复按f12&#xff0c;不同电脑型号可自行查阅)把硬盘模式从raid调整为ahci(System configuration–&#xff…

方差和标准差的意义

文章目录案例&#xff1a;箭靶案例&#xff1a;身高案例&#xff1a;身高体重在此前一篇文章 《算法效果评估&#xff1a;均方根误差&#xff08;RMSE&#xff09;/ 标准误差》中&#xff0c;我们介绍了方差/标准差的计算方法&#xff0c;也点出了它们是用来“度量数据离散程度…