Mycat2 分布式数据库中间件

news2024/12/27 11:56:48

一.安装部署

Mycat2目前还不支持直接获取Docker镜像,需要自己通过Dockerfile打包镜像,其实这也是为了开发者考虑,比如一些个性化功能,如自定义分片等

Dockerfile
FROM docker.io/adoptopenjdk/openjdk8:latest


ENV AUTO_RUN_DIR ./mycat2
ENV DEPENDENCE_FILE mycat2-1.20-jar-with-dependencies.jar
ENV TEMPLATE_FILE mycat2-install-template-1.21.zip

#设置阿里云源,下载快一点
RUN sed -i "s@http://.*archive.ubuntu.com@http://mirrors.aliyun.com@g" /etc/apt/sources.list
RUN sed -i "s@http://.*security.ubuntu.com@http://mirrors.aliyun.com@g" /etc/apt/sources.list

RUN buildDeps='procps wget unzip' \
    && apt-get update \
    && apt-get install -y $buildDeps


RUN wget -P  $AUTO_RUN_DIR/ http://dl.mycat.org.cn/2.0/1.20-release/$DEPENDENCE_FILE \
   &&  wget -P  $AUTO_RUN_DIR/ http://dl.mycat.org.cn/2.0/install-template/$TEMPLATE_FILE

RUN cd $AUTO_RUN_DIR/ \
    && unzip $TEMPLATE_FILE \
    && ls -al . \
    && mv  $DEPENDENCE_FILE mycat/lib/ \
    && chmod +x  mycat/bin/* \
    && chmod 755  mycat/lib/* \
    && mv mycat /usr/local

#copy mycat /usr/local/mycat/

VOLUME /usr/local/mycat/conf
VOLUME /usr/local/mycat/logs


EXPOSE 8066 1984

CMD ["/usr/local/mycat/bin/mycat", "console"]

二.编译镜像 

#如果执行目录不是Dockerfile所在目录,需要-f指定
docker build -t mycat2:1.20 .

三.创建容器

docker run -d --name=mycat2 -p 8066:8066 -p 1984:1984 -v /usr/local/mycat/conf:/usr/local/mycat/conf -v /usr/local/mycat/logs:/usr/local/mycat/logs  mycat2:1.20
#会启动失败,因为数据库配置不对,要改数据库链接才行

vi  /usr/local/mycat/conf/datasources/prototypeDs.datasource.json

#jdbc:mysql://192.168.88.192:3306

# 复制容器内配置
mkdir /usr/local/mycat
cd /usr/local/mycat
docker cp mycat2:/usr/local/mycat/conf .
docker cp mycat2:/usr/local/mycat/logs .

四.docker-compose.yml

version: '3.3'
services:
  mycat2:
    build:
      context: ./
      dockerfile: Dockerfile
    image: mycat2:1.20
    container_name: mycat2
    ports:
     - 8066:8066
    links:
     - mysql1
     - mysql2
    volumes:
      - /usr/local/mycat/conf:/usr/local/mycat/conf
      - /usr/local/mycat/logs:/usr/local/mycat/logs

配置文件修改

我们将要使用mycat2实现读写分离,所以前提是需要将数据库设置为主从复制模式(不然读的永远为空),3306端口为master,3307端口为slave

数据源配置
cd /usr/local/mycat/conf/datasources

#从原生配置复制两个json文件
[root@localhost datasources]# cp prototypeDs.datasource.json master01.datasource.json
[root@localhost datasources]# cp prototypeDs.datasource.json slave01.datasource.json
[root@localhost datasources]# ls
master01.datasource.json  prototypeDs.datasource.json  slave01.datasource.json

#master01.datasource.json
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"master01",
        "password":"root",
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.88.192:3306?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"root",
        "weight":0
}

#slave01.datasource.json
{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"slave01",
        "password":"root",
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.88.192:3307?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"root",
        "weight":0
}

数据源集群配置
#clusters/prototype.cluster.json

{
        "clusterType":"MASTER_SLAVE",
        "heartbeat":{
                "heartbeatTimeout":1000,
                "maxRetry":3,
                "minSwitchTimeInterval":300,
                "slaveThreshold":0
        },
        "masters":[
                "master01" #写
        ],
        "replicas":[
        		"slave01" #读
        ],
        "maxCon":200,
        "name":"prototype",
        "readBalanceType":"BALANCE_ALL",
        "switchType":"SWITCH"
}

物理库配置
#schemas/matomo_tj.schema.json

{
    # 物理库
    "schemaName": "matomo_tj",
    # 指向集群,或者数据源
    "targetName": "prototype"
}

Mycat2 登录用户配置
#users/root.user.json
{
        "dialect":"mysql",
        #ip 为 null,允许任意 ip 登录
        "ip":null,
        "password":"root",
        "transactionType":"proxy",
        "username":"root"
}

测试连接

测试1:

通过mycat2 执行插入,会发现master01,slave01都有相同的数据

测试2:

手动修改slave01数据,通过mycat2进行查询,会发现查询的数据为slave01的数据

测试3:

修改/clusters/prototype.cluster.json

{
        "clusterType":"GARELA_CLUSTER", //改为集群模式
        "heartbeat":{
                "heartbeatTimeout":1000,
                "maxRetry":3,
                "minSwitchTimeInterval":300,
                "slaveThreshold":0
        },
        "masters":[  //多主模式
                "master01",
                "slave01"
        ],
        //"replicas":[
        //      "slave01"
        //],
        "maxCon":200,
        "name":"prototype",
        "readBalanceType":"BALANCE_ALL",
        "switchType":"SWITCH"
}

 关闭masters中任意服务器,然后通过mycat 8066进行数据插入操作,会发现剩下的那台服务器承接了write操作(HA)

Zookeeper统一管理
Zookeeper是个好东西,基本上涉及元数据的服务都可以使用它来实现或者辅助实现高可用集群,Mycat2也盯上了它

其实在这里我们使用Zookeeper作为配置中心,存储Mycat2的配置,以及提供元数据锁和znode监听的功能,简单可以称其为:统一配置中心

zookeeper docker安装配置:

version: '3.3'
services:
  zookeeper:
    container_name: zookeeper
    image: debezium/zookeeper
    ports:
      - 2181:2181

我们 zookeeper客户端来可视化操作比较方便,工具下载:https://issues.apache.org/jira/secure/attachment/12436620/ZooInspector.zip

解压后进入build,通过java -jar zookeeper-dev-ZooInspector.jar 启动窗口

点击运行按钮输入zookeeper地址即可看到zookeeper的数据结构信息了:

下面开始在mycat2的server.json文件配置zookeeper地址信息进行注册 

#1、server.json改这两个信息就够了
"mode":"cluster",
"properties":{
   "zk_address":"192.168.88.192:2181"
}

#2、docker restart mycat2

#3、使用ZooInspector登录该zk,编辑里面的mycat配置即可,除了server级别配置,其他配置schema,user,cache,sequence,datasource,cluster.都可以实现热更新,在ZK里编辑相当于直接更改配置文件,暂时无法自动创建物理库,物理表.

分库分表
概念
分库分表就是为了解决由于数据量过大而导致数据库性能降低的问题,将原来独立的数据库拆分成若干数据库组成,将数据大表分成若干数据表组成,使得单一数据库、单一数据表的数据量变小,从而达到提升数据库性能的目的。而且随着微服务这种架构的兴起,我们应用从一个完整的大的应用,切分为很多可以独立提供服务的小应用,每个应用都有独立的数据库。数据的切分分为两种:

l **垂直切分:**按照业务模块进行切分,将不同模块的表切分到不同的数据库中。

l 水平切分:将一张大表按照一定的切分规则,按照行切分到不同的表或者不同的库中

mycat2分库分表包括两种方式:

SQL脚本命令分库分表,同时会在schemas下生成对应的json文件
schemas下通过配置的方式进行分库分表
广播表(全局表)
这个其实不属于分库分表的范畴,只是对于分库分表来说,有些数据是公共的,比如数据字典,在每个库中都需要相同的数据

顾名思义,大喇叭声音谁都听得见,所有库表都会收到相同数据,我们这里使用单一节点,就两个数据源,master01,master02(注意这两个库不要存在主从复制设置,或者在之前的slave库执行:stop slave;) 

数据源master01.datasource.json

{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"master01",
        "password":"root",
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.88.192:3306/matomo_tj?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"root",
        "weight":0
}

 数据源master02.datasource.json

{
        "dbType":"mysql",
        "idleTimeout":60000,
        "initSqls":[],
        "initSqlsGetConnection":true,
        "instanceType":"READ_WRITE",
        "maxCon":1000,
        "maxConnectTimeout":3000,
        "maxRetryCount":5,
        "minCon":1,
        "name":"master02",
        "password":"root",
        "type":"JDBC",
        "url":"jdbc:mysql://192.168.137.128:3307/matomo_tj?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=UTF-8",
        "user":"root",
        "weight":0
}

集群c0.cluster.json

{
        "clusterType":"SINGLE_NODE",
        "heartbeat":{
                "heartbeatTimeout":1000,
                "maxRetry":3,
                "minSwitchTimeInterval":300,
                "slaveThreshold":0
        },
        "masters":[
                "master01"
        ],
        "maxCon":200,
        "name":"c0",
        "readBalanceType":"BALANCE_ALL",
        "switchType":"SWITCH"
}

 集群c1.cluster.json

{
        "clusterType":"SINGLE_NODE",
        "heartbeat":{
                "heartbeatTimeout":1000,
                "maxRetry":3,
                "minSwitchTimeInterval":300,
                "slaveThreshold":0
        },
        "masters":[
                "master02"
        ],
        "maxCon":200,
        "name":"c1",
        "readBalanceType":"BALANCE_ALL",
        "switchType":"SWITCH"
}

 登录mycat2,创建逻辑库,广播表,并插入数据,会发现在master01,master02都会有相同的库表结构及数据

CREATE DATABASE db1;
USE db1;
CREATE TABLE `travelrecord` (
	`id` BIGINT NOT NULL auto_increment,
	`user_id` VARCHAR ( 100 ) DEFAULT NULL,
	`traveldate` date DEFAULT NULL,
	`fee` DECIMAL ( 10, 0 ) DEFAULT NULL,
	`days` INT DEFAULT NULL,
	`blob` LONGBLOB,
	PRIMARY KEY ( `id` ),
KEY `id` ( `id` ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8 BROADCAST;

INSERT INTO `db1`.`travelrecord` (`id`, `user_id`, `traveldate`, `fee`, `days`, `blob`) VALUES (1, '1', '2022-08-12', 1, 1, NULL);
INSERT INTO `db1`.`travelrecord` (`id`, `user_id`, `traveldate`, `fee`, `days`, `blob`) VALUES (2, '2', '2022-08-12', 2, 2, NULL);

 分片表

mycat2分片可以使用SQL脚本和schema配置,内置Hash分片策略,targetIndexdbIndextableIndex总是从0开始计算,支持groovy运算生成目标名,库名,表名 

Hash分片(SQL)

官网截图,可惜有个错误:YYYYDD应该是按年日哈希

需求:进行站点访问统计,按访问年份分库,按访问站点分表

分析:这个地方需要用到取模哈(MOD_HASH)希和按年月哈希(YYYYMM)

登录mycat2,创建逻辑库,分片表,并插入数据,即将采用的最终策略按如下“斜体”计算

MOD_HASH

分库键和分表键是同键

分表下标=分片值%(分库数量*分表数量)

分库下标=分表下标/分表数量

分库键和分表键是不同键

分表下标=分片值%分表数量

分库下标=分表下标%分库数量

YYYYMM

仅用于分库

(YYYY*12+MM)%分库数

DROP DATABASE db2;
CREATE DATABASE db2;
USE db2;
DROP TABLE IF EXISTS `matomo_log_visit_material`;
CREATE TABLE `matomo_log_visit_material`  (
  `idvisit` BIGINT(100) NOT NULL AUTO_INCREMENT COMMENT '访问记录主键',
  `idsite` bigint(20) NULL DEFAULT NULL COMMENT '站点id',
  `user_id` tinytext CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT '用户id',
  `visit_first_action_time` datetime NULL DEFAULT NULL COMMENT '访问的第一个动作的日期时间',
  `visit_total_time` int(11) NULL DEFAULT NULL COMMENT '停留总时间',
  `visit_goal_buyer` tinyint(1) NULL DEFAULT NULL COMMENT '是否购买',
  `referer_type` tinyint(1) NULL DEFAULT NULL COMMENT '用户来源',
  `location_ip` varbinary(16) NULL DEFAULT NULL COMMENT '访问者ip',
  PRIMARY KEY (`idvisit`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '用户访问数据素材表' ROW_FORMAT = COMPACT dbpartition by YYYYMM (visit_first_action_time) dbpartitions 8
tbpartition by MOD_HASH (idsite) tbpartitions 3;

DELETE FROM `db2`.`matomo_log_visit_material`;
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (1, '1', '2022-01-12 16:32:13', 1, 1, 1, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (2, '2', '2021-02-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (3, '1', '2020-03-12 16:32:13', 1, 1, 1, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (1, '2', '2019-04-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (2, '1', '2018-05-12 16:32:13', 1, 1, 1, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (3, '2', '2017-06-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (1, '1', '2016-07-12 16:32:13', 1, 1, 1, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (2, '2', '2015-08-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (3, '1', '2014-09-12 16:32:13', 1, 1, 1, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (1, '2', '2013-10-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (2, '2', '2012-11-12 16:32:32', 2, 2, 2, NULL);
INSERT INTO `db2`.`matomo_log_visit_material` (`idsite`, `user_id`, `visit_first_action_time`, `visit_total_time`, `visit_goal_buyer`, `referer_type`, `location_ip`) VALUES (3, '2', '2011-12-12 16:32:32', 2, 2, 2, NULL);

我们拿第一条数据来看:

分库按(2022*12+1)% 8 = 1,数据库下标为1

分表按1%3 = 1,数据表下标为1

Hash分片(Schema)

其实,我们通过SQL脚本执行的分片策略,会在schemas下生成对应的json配置文件,如上面两节我们就可以看到对应的文件:

打开可以看到,其实就是SQL脚本解析生成的: 

{
        "customTables":{},
        "globalTables":{},
        "normalTables":{},
        "schemaName":"db2",
        "shardingTables":{
                "matomo_log_visit_material":{
                        "createTableSQL":"CREATE TABLE db2.`matomo_log_visit_material` (\n\t`idvisit` BIGINT(100) NOT NULL AUTO_INCREMENT COMMENT '访问记录主键',\n\t`idsite` bigint(20) NULL DEFAULT NULL COMMENT '站点id',\n\t`user_id` tinytext CHARACTER SET utf8 COLLATE utf8_bin NULL COMMENT '用户id',\n\t`visit_first_action_time` datetime NULL DEFAULT NULL COMMENT '访问的第一个动作的日期时间',\n\t`visit_total_time` int(11) NULL DEFAULT NULL COMMENT '停留总时间',\n\t`visit_goal_buyer` tinyint(1) NULL DEFAULT NULL COMMENT '是否购买',\n\t`referer_type` tinyint(1) NULL DEFAULT NULL COMMENT '用户来源',\n\t`location_ip` varbinary(16) NULL DEFAULT NULL COMMENT '访问者ip',\n\tPRIMARY KEY USING BTREE (`idvisit`)\n) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = COMPACT COMMENT '用户访问数据素材表'\nDBPARTITION BY YYYYMM(visit_first_action_time) DBPARTITIONS 8\nTBPARTITION BY MOD_HASH(idsite) TBPARTITIONS 3",
                        "function":{
                                "properties":{
                                        "dbNum":"8",
                                        "mappingFormat":"c${targetIndex}/db2_${dbIndex}/matomo_log_visit_material_${tableIndex}",
                                        "tableNum":"3",
                                        "tableMethod":"MOD_HASH(idsite)",
                                        "storeNum":2,
                                        "dbMethod":"YYYYMM(visit_first_action_time)"
                                },
                                "ranges":{}
                        },
                        "partition":{

                        },
                        "shardingIndexTables":{}
                }
        },
        "views":{}
}

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

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

相关文章

【软考-中级】系统集成项目管理工程师 【17 信息系统安全管理】

持续更新。。。。。。。。。。。。。。。 【第十七章】信息系统安全管理 (选择2分 17.1 信息安全管理17.1.1 信息安全含义和目标 17.2 信息系统安全17.2.1信息系统安全概念17.2.2信息系统安全属性17.2.3信息系统安全管理体系 17.3 物理安全管理17.3.1计算机机房与设施安全17.3.…

Postman入门基础 —— 接口测试流程!

一、编写接口测试计划 接口测试计划和功能测试计划目标一致,都是为了确认需求、确定测试环境、确定测试方法,为设计测试用例做准备,初步制定接口测试进度方案。一般来说,接口测试计划包括概述、测试资源、测试功能、测试重点、测…

【C++】用constexpr,constinit,consteval让程序跑的快一点

从C11加入constexpr关键字开始,到C20又加入了consteval ,constinit ,有3个const打头的关键字 虽然是以const开头的,不过这3个关键字主要是指示在编译时候的动作,它们都是在编译时就已经被编译程序处理,并非…

Python使用openpyxl读取excel图片

使用openpyxl读取excel中图片,并保存到本地. 需要的包。 from openpyxl import load_workbook from PIL import Image import cv2 import numpy as np具体实现 先把openpyxl读取的图片转换为Image对象,再将Image对象转换为numpy array,num…

【无标题】Docker入门到拿捏,图文码并茂

0. 项目部署的问题 大型项目组件较多,运行环境也较为复杂,部署时会碰到- -些问题: 依赖关系复杂,容易出现兼容性问题开发、测试、生产环境有差异 1. 认识Docker Docker如何解决依赖的兼容问题的? 将应用的Libs (函数库)、Deps (依赖)、配置与应用一…

V8引擎编译原理(VIP课程)

什么是V8 V8是谷歌的开源高性能JavaScript和WebAssembly引擎,用C编写。它被用于Chrome和Node.js等。它实现ECMAScript和WebAssembly,并在Windows 7或更高版本、macOS 10.12以及使用x64、IA-32、ARM或MIPS处理器的Linux系统上运行。V8可以独立运行&#…

KMP substring search 算法 案例分析

一、理解KMP算法如何运用后缀和前缀的信息 文本串text:abcxabcdabxabcdabcdabcy模式串pattern:abcdabcy 当发现不匹配的点,我们的目标不是在这个串中进行回溯操作。因此我们要检查的是 d 的前面的子串(abc),在这个子串&#xff08…

【Qt-19】按Q退出应用程序

如何将Qt窗口应用程序改成控制台程序呢&#xff1f; 下面进入正文&#xff0c;如何控制控制台程序退出呢&#xff1f; 这里采用线程方式&#xff0c;通过单独线程监视用户输入来执行是否退出程序。 监视线程头文件thread.h #include <QThread> #include "TDRServe…

c++_learning-基础部分

文章目录 基础认识&#xff1a;语言特性&#xff08;面向对象编程&#xff09;&#xff1a;c的类&#xff08;相当于c中的结构体&#xff09;&#xff1a;三大特性&#xff1a;c包含四种编程范式&#xff1a;优缺点&#xff1a; c程序编译的过程&#xff1a;预处理->编译&am…

matlab中绘制 维诺图(Voronoi Diagram)

1.专业术语&#xff08;相关概念&#xff09;&#xff1a; 基点Site&#xff1a;具有一些几何意义的点 细胞Cell&#xff1a;这个Cell中的任何一个点到Cell中基点中的距离都是最近的&#xff0c;离其他Site比离内部Site的距离都要远。 Cell的划分&#xff1a;基点Site与其它的…

气膜式仓库:灵活创新,助力企业储存与物流升级

气膜式大空间仓库的建设不受地面条件限制&#xff0c;为企业提供了极大的便利。合理的仓储系统不仅是企业和厂商提高货品流动速度、确保生产、储运、配送顺利进行的关键&#xff0c;也是现代物流发展的需要。传统建筑在使用中存在一些不足&#xff0c;因此&#xff0c;我们需要…

科技新宠!拓世AI智能直播一体机揭秘,颠覆教学模式!

数字时代的铺展下&#xff0c;短视频和直播电商行业呈现出爆发式的增长&#xff0c;这种趋势正在日益融入人们的日常生活中&#xff0c;让短视频带货和直播带货逐渐成为一种独具中国特色的现象。与此同时&#xff0c;市场对专业人才的渴求也日渐加剧。国家以及相关地方政府纷纷…

Generative AI 新世界 | 大模型参数高效微调和量化原理概述

在上期文章&#xff0c;我们对比了在 Amazon SageMaker 上部署大模型的两种不同的部署方式。本期文章&#xff0c;我们将探讨两个目前大语言模型领域的开发者们都关注的两个热门话题&#xff1a;大型语言模型&#xff08;LLM&#xff09;的高效微调和量化。 微调大型语言模型允…

微信小程序调起微信支付

微信支付开发文档&#xff1a;wx.requestPayment(Object object) | 微信开放文档 一、先有一个提交订单页面 &#xff08;1&#xff09;wxml <view class"btn" bindtap"addOrder">{{btnText}}</view> 二、接入支付流程 &#xff08;1&…

element-ui 图片压缩上传

picture.js export const compressImgNew (file) > {return new Promise(resolve > {const reader new FileReader()const image new Image()image.onload (imageEvent) > {const canvas document.createElement(canvas) // 创建画布const context canvas.getCo…

工控机连接Profinet转Modbus RTU网关与水泵变频器Modbus通讯配置案例

Profinet转Modbus RTU网关是一个具有高性能的通信设备&#xff0c;它能够将工控机上的Profinet协议转换成水泵变频器可识别的Modbus RTU协议&#xff0c;实现二者之间的通信。通过这种方式&#xff0c;工控机可以直接控制水泵变频器的运行状态&#xff0c;改变其工作频率&#…

获取钉钉机器人的token及secret

一、下载安装 app不能自定义机器人&#xff0c;要客户端才行 二、进入组织/团队 三、创建群聊 1、发起群聊 2、创建内存群 群聊是内部的才行&#xff0c;只有内部的才支持自定义机器人 3、选中联系人 4、进入群设置 四、创建自定义机器人 1&#xff09; 进入机器人页面 2&…

工程云平台源码 建筑工地劳务实名制、危大工程监管平台源码

智慧工地的核心是数字化&#xff0c;它通过传感器、监控设备、智能终端等技术手段&#xff0c;实现对工地各个环节的实时数据采集和传输&#xff0c;如环境温度、湿度、噪音等数据信息&#xff0c;将数据汇集到云端进行处理和分析&#xff0c;生成各种报表、图表和预警信息&…

TSINGSEE风电场可视化智能视频集控监管系统,助力风电场无人值守监管新模式

一、方案背景 风能作为一种清洁的可再生能源&#xff0c;对于我国实现“双碳”目标尤为重要。风电场一般地处偏远地区&#xff0c;占地广、面积大&#xff0c;并且风机分布区域广泛、现场运行设备巡视难度大、及时性差。原有的监管系统智能化水平低&#xff0c;满足不了日常的…

腾讯待办关停什么意思?可替代的待办提醒软件来了

对于国内的成年人来说&#xff0c;几乎每个人都有至少一个微信账号要和亲朋好友、同事联系&#xff0c;而如果想要记录一些待办事项并准时接收提醒的话&#xff0c;可以直接在微信中使用“腾讯待办”这个小程序来记录待办事项并设置提醒时间。 不过值得注意的是&#xff0c;腾…