基于Sharding-jdbc实现水平分库、垂直分库、读写分离

news2024/12/15 19:40:29

一、实现水平分库

需求说明

水平分库是把同一个表的数据按一定规则拆到不同的数据库中,每个库可以放在不同的服务器上。
接下来咱们继续对快速入门中的例子进行完善。

实现步骤

将原有order_db库拆分为order_db_1、order_db_2

CREATE DATABASE order_db_1 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
CREATE DATABASE order_db_2 CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

再分别对每个库建立同样的表结构

DROP TABLE IF EXISTS t_order_1;

CREATE TABLE t_order_1 (
	`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',
	`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',
	`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',
	`status` VARCHAR ( 50 ) CHARACTER 
	SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
	PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

DROP TABLE IF EXISTS t_order_2;

CREATE TABLE t_order_2 (
	`order_id` BIGINT ( 20 ) NOT NULL COMMENT '订单id',
	`price` DECIMAL ( 10, 2 ) NOT NULL COMMENT '订单价格',
	`user_id` BIGINT ( 20 ) NOT NULL COMMENT '下单用户id',
	`status` VARCHAR ( 50 ) CHARACTER 
	SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '订单状态',
	PRIMARY KEY ( `order_id` ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

 在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_shuiping_dbsharding
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true

# 以下配置为sharding-jdbc分片规则配置

# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m1,m2
#数据源连接数据库
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db_1?useUnicode=true
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456

spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/order_db_2?useUnicode=true
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123456

# 2.指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m$->{1..2}.t_order_$->{1..2}

# 3.指定t_order表中的主键生成策略

#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE

# 4.指定t_order表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中

#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1}

# 5.指定分库策略

#告诉分库需要采用的分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.shardingColumn=user_id
#确定采取什么样的分库算法
spring.shardingsphere.sharding.tables.t_order.databaseStrategy.inline.algorithmExpression=m$->{user_id % 2 + 1}

# 6.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true


# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

mapper代码如下:

@Mapper
public interface OrderMapper {
    /**
     * 这里t_order就是sharding-jdbc中的逻辑表
     */
    @Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")
    public int insertOrder(Order order);

    @Select("<script>" +
            "select " +
            "* " +
            "from t_order t " +
            "where t.order_id in " +
            "<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            " AND user_id = #{userId}" +
            "</script>")
    public List<Map> selectListByUserIdAndOrderIds(@Param("userId") Long userId,@Param("orderIds") List<Long> orderIds);
}

 测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingShuipingDBShardingApplicationTests {

    @Autowired
    private OrderMapper orderMapper;

    @Test
    public void insertDBShardingTest(){
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setStatus("success_"+i);
            order.setUserId(1L);
            order.setPrice(new BigDecimal((i+1)*5));
            int result = orderMapper.insertOrder(order);
            System.out.println(result);
        }

        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setStatus("success_"+i);
            order.setUserId(2L);
            order.setPrice(new BigDecimal((i+1)*5));
            int result = orderMapper.insertOrder(order);
            System.out.println(result);
        }
    }

    @Test
    public void selectDBShardingTest(){
        List<Long> orderIds = new ArrayList<>();
        orderIds.add(1074752838191546368L);
        orderIds.add(1074752838183157761L);
        Long userId = 2L;
        List<Map> maps = orderMapper.selectListByUserIdAndOrderIds(userId,orderIds);
        for (Map map : maps) {
            System.out.println(map);
        }
    }
}

二、实现垂直分库

需求说明

是指按照业务将表进行分类,分布到不同的数据库上面,每个库可以放在不同的服务器上,它的核心理念是专库专用。接下来看一下在单库中实现垂直分库操作。

实现步骤

新增user数据库

#创建数据库 
CREATE DATABASE user_db CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';

#创建表
DROP TABLE IF EXISTS t_user;

CREATE TABLE t_user (
	user_id BIGINT ( 20 ) NOT NULL COMMENT '用户id',
	fullname VARCHAR ( 255 ) CHARACTER 
	SET 'utf8' COLLATE 'utf8_general_ci' NOT NULL COMMENT '用户姓名',
	user_type CHAR ( 1 ) DEFAULT NULL COMMENT '用户类型',
	PRIMARY KEY ( user_id ) USING BTREE 
) ENGINE = INNODB CHARACTER 
SET = 'utf8' COLLATE = 'utf8_general_ci' ROW_FORMAT = Dynamic;

  在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_chuizhi_dbsharding
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true

# 以下配置为sharding-jdbc分片规则配置

# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m1,m2
#order数据源连接数据库
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/order_db?useUnicode=true
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123456
#user数据源连接数据库
spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/user_db?useUnicode=true
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=123456

# 2.指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=m1.t_order_$->{1..2}

# 2.1 指定t_order表中的主键生成策略

#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE

# 2.2 指定t_order表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中

#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.shardingColumn=order_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_order.tableStrategy.inline.algorithmExpression=t_order_$->{order_id % 2 + 1}

# 3 指定订单表的数据分布情况,配置数据节点 下面的't_order'是逻辑表,这个名字可以自己起一个   m1.t_order_$->{1..2}表示利用行表达式来实现动态表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m2.t_user

# 3.1 指定t_user表中的主键生成策略

#表示告诉sharding-jdbc数据库表中的那一个字段进行主键生成
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
#指定具体的主键生成策略  -> 雪花算法
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

# 3.2 指定t_user表的分片策略(分片策略=分片键+分片算法):主键为偶数路由到t_order_1中,否则插入到t_order_2中

#告诉分片键是哪一个字段
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.shardingColumn=user_id
#确定采取什么样的分片算法
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.algorithmExpression=t_user

# 4.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true


# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

 添加userMapper接口

@Mapper
public interface UserMapper {
    /**
     * 这里t_order就是sharding-jdbc中的逻辑表
     */
    @Insert("insert into t_user(fullname,user_type) values(#{fullname},#{userType})")
    public int insertUser(@Param("fullname") String fullname,@Param("userType") String userType);

    @Select("<script>" +
            "select " +
            "* " +
            "from t_user t " +
            "where t.user_id in " +
            "<foreach collection='userIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    public List<Map> selectListByUserIds(@Param("userIds") List<Long> userIds);
}

  添加orderMapper接口

@Mapper
public interface OrderMapper {
    /**
     * 这里t_order就是sharding-jdbc中的逻辑表
     */
    @Insert("insert into t_order(price,user_id,status) values(#{price},#{userId},#{status})")
    public int insertOrder(Order order);

    @Select("<script>" +
            "select " +
            "* " +
            "from t_order t " +
            "where t.order_id in " +
            "<foreach collection='orderIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    public List<Map> selectListByOrderIds(@Param("orderIds") List<Long> orderIds);
}

测试代码如下

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingChuizhiDBShardingApplicationTests {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserMapper userMapper;

    @Test
    public void insertOrderTest(){
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setStatus("success_"+i);
            order.setUserId(1L);
            order.setPrice(new BigDecimal((i+1)*5));
            int result = orderMapper.insertOrder(order);
            System.out.println(result);
        }
    }

    @Test
    public void selectOrderTest(){
        List<Long> orderIds = new ArrayList<>();
        orderIds.add(1074752838191546368L);
        orderIds.add(1074752838183157761L);
        List<Map> maps = orderMapper.selectListByOrderIds(orderIds);
        for (Map map : maps) {
            System.out.println(map);
        }
    }

    @Test
    public void insertUserTest(){
        for (int i = 0; i < 10; i++) {
            userMapper.insertUser("lcc"+i,i+"");
        }
    }

    @Test
    public void selectUserTest(){
        List<Long> userIds = new ArrayList<>();
        userIds.add(1074769306459308033L);
        userIds.add(1074769306564165632L);
        List<Map> maps = userMapper.selectListByUserIds(userIds);
        for (Map map : maps) {
            System.out.println(map);
        }
    }
}

可以发现,不同的表会去到不同的数据库 

三、实现读写分离

什么是读写分离

面对日益增加的系统访问量,数据库的吞吐量面临着巨大瓶颈。 对于同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。

通过一主多从的配置方式,可以将查询请求均匀的分散到多个数据副本,能够进一步的提升系统的处理能力。 使用多主多从的方式,不但能够提升系统的吞吐量,还能够提升系统的可用性,可以达到在任何一个数据库宕机,甚至磁盘物理损坏的情况下仍然不影响系统的正常运行。

读写分离和分库分表有什么关系呢

读写分离的数据节点中的数据内容是一致的,而水平分片的每个数据节点的数据内容却并不相同。将水平分片和读写分离联合使用,能够更加有效的提升系统的性能。

Sharding-JDBC读写分离则是根据SQL语义的分析,将读操作和写操作分别路由至主库与从库。它提供透明化读写分离,让使用方尽量像使用一个数据库一样使用主从数据库集群。

所以,基于Sharding-jdbc的读写分离只是将写请求路由到一个节点上,读请求路由到另一个节点上,而其中这些数据库节点数据之间的同步由数据库内部或者其他中间件完成,这不是Sharding-jdbc需要完成的。

docker搭建mysql一主一从架构

我们将基于MySQL:5.7.41版本进行搭建

主节点环境搭建

主节点文件夹创建

mkdir /usr/local/mysql_zhu_cong/mysql_master/data
mkdir /usr/local/mysql_zhu_cong/mysql_master/log
mkdir /usr/local/mysql_zhu_cong/mysql_master/conf

主节点文件配置

vim /usr/local/mysql_zhu_cong/mysql_master/conf/my.cnf

 文件内容如下:

[mysqld]
character_set_server=utf8

#开启日志
log-bin=mysql-bin
#设置服务id,主从服务不能一致
server-id=1

#设置需要同步的数据库
binlog-do-db=user_db

#屏蔽系统库同步
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema

 启动容器

docker run --name mysql_zhu_cong_master \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /usr/local/mysql_zhu_cong/mysql_master/data:/var/lib/mysql \
-v /usr/local/mysql_zhu_cong/mysql_master/log:/var/log/mysql \
-v /usr/local/mysql_zhu_cong/mysql_master/conf:/etc/mysql/conf.d \
-dp 3316:3306 \
mysql:5.7.41

从节点环境搭建

从节点文件夹创建

mkdir /usr/local/mysql_zhu_cong/mysql_slave

#复制主节点信息
cp -r /usr/local/mysql_zhu_cong/mysql_master/data /usr/local/mysql_zhu_cong/mysql_slave/
cp -r /usr/local/mysql_zhu_cong/mysql_master/log /usr/local/mysql_zhu_cong/mysql_slave/
cp -r /usr/local/mysql_zhu_cong/mysql_master/conf /usr/local/mysql_zhu_cong/mysql_slave/

请注意,主从 MySQL下的数据(data)目录下有个文件auto.cnf,文件中定义了uuid,要保证主从数据库实例的 uuid不一样,建议直接删除掉,重启服务后将会重新生成。

rm /usr/local/mysql_zhu_cong/mysql_slave/data/auto.cnf

编辑从节点配置文件

vim /usr/local/mysql_zhu_cong/mysql_slave/conf/my.cnf

 文件内容如下:

[mysql]
default_character_set=utf8
[mysqld]
character_set_server=utf8

#开启日志
log-bin=mysql-bin
#设置服务id,主从服务不能一致
server-id=2

#设置需要同步的数据库
replicate_wild_do_table=user_db.%

#屏蔽系统库同步
replicate_wild_ignore_table=mysql.%
replicate_wild_ignore_table=information_schema.%
replicate_wild_ignore_table=performance_schema.%

 启动容器

docker run --name mysql_zhu_cong_slave \
-e MYSQL_ROOT_PASSWORD=123456 \
-v /usr/local/mysql_zhu_cong/mysql_slave/data:/var/lib/mysql \
-v /usr/local/mysql_zhu_cong/mysql_slave/log:/var/log/mysql \
-v /usr/local/mysql_zhu_cong/mysql_slave/conf:/etc/mysql/conf.d \
-dp 3326:3306 \
mysql:5.7.41

主从同步搭建

连接上主节点,执行以下命令

--授权主备复制专用账号
GRANT replication SLAVE ON *.* TO 'db_sync'@'%' IDENTIFIED by 'db_sync';
--刷新权限
FLUSH PRIVILEGES;
--确认位点 记录下文件名以及位点 
SHOW MASTER STATUS;

得到以下结果:

 

 连接上从节点,执行以下命令

--先停止同步 
STOP SLAVE; 
--修改从库指向主库,使用上一步记录的文件名以及位点 
CHANGE MASTER TO master_host='192.168.149.128',master_port=3316, master_user='db_sync', master_password='db_sync', master_log_file='mysql-bin.000002', master_log_pos=584; 
--启动同步 
START SLAVE; 
--查看从库状态Slave_IO_Running和Slave_SQL_Runing都为yes说明同步成功,如果不为yes,请 检查error_Log,然后排查相关异常 
SHOW SLAVE STATUS

在上面的命令中, 第二条命令,其中的master_log_file='mysql-bin.000002', master_log_pos=584两个配置项就是根据上面标红部分叫你记下来的内容

验证

修改master中的user_db,如下:

 

打开slave中的user_db,我们发现,已经自动将修改后的结果同步过来了

至此,读写分离的MySQL环境已经搭建完毕

Sharding-jdbc代码实现

在application.properties中配置分片分库规则

# 端口号
server.port=56000
# 应用名称
spring.application.name=sharding_duxiefenli
# 表示spring中发现的bean会覆盖之前相同名称的bean
spring.main.allow-bean-definition-overriding=true
# 该配置项,将数据库中带有下划线的字段名称映射成驼峰命名
mybatis.configuration.map-underscore-to-camel-case=true

# 以下配置为sharding-jdbc分片规则配置

# 1.定义数据源
#定义数据源名称
spring.shardingsphere.datasource.names=m0,s0
#order数据源连接数据库
spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://192.168.149.128:3316/user_db?useUnicode=true
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123456
#user数据源连接数据库
spring.shardingsphere.datasource.s0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url=jdbc:mysql://192.168.149.128:3326/user_db?useUnicode=true
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=123456

# 2.主库从库逻辑数据源定义ds0为user_db,指定谁是主库,谁是从库
spring.shardingsphere.sharding.master-slave-rules.ds0.masterDataSourceName=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slaveDataSourceNames=s0

# 3.配置分片策略
spring.shardingsphere.sharding.tables.t_user.actualDataNodes=ds0.t_user
#分片键
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.shardingColumn=user_id
#分片算法
spring.shardingsphere.sharding.tables.t_user.tableStrategy.inline.algorithmExpression=t_user

# 4.配置主键生成策略
spring.shardingsphere.sharding.tables.t_user.keyGenerator.column=user_id
spring.shardingsphere.sharding.tables.t_user.keyGenerator.type=SNOWFLAKE

# 5.指定,打开sharding-jdbc提供的sql输出日志配置
spring.shardingsphere.props.sql.show=true


# 日志配置
logging.level.root=info
logging.level.org.springframework=info
logging.level.com.lcc=debug
logging.level.druid.sql=debug

userMapper代码如下:

@Mapper
public interface UserMapper {
    /**
     * 这里t_order就是sharding-jdbc中的逻辑表
     */
    @Insert("insert into t_user(fullname,user_type) values(#{fullname},#{userType})")
    public int insertUser(@Param("fullname") String fullname,@Param("userType") String userType);

    @Select("<script>" +
            "select " +
            "* " +
            "from t_user t " +
            "where t.user_id in " +
            "<foreach collection='userIds' item='id' open='(' separator=',' close=')'>" +
            "#{id}" +
            "</foreach>" +
            "</script>")
    public List<Map> selectListByUserIds(@Param("userIds") List<Long> userIds);
}

测试代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingDuxiefenliApplicationTests {


    @Autowired
    private UserMapper userMapper;


    @Test
    public void insertUserTest(){
        for (int i = 0; i < 10; i++) {
            userMapper.insertUser("lcc_duxiefenli_"+i,i+"");
        }
    }

    @Test
    public void selectUserTest(){
        List<Long> userIds = new ArrayList<>();
        userIds.add(1074769306459308033L);
        userIds.add(1074769306564165632L);
        List<Map> maps = userMapper.selectListByUserIds(userIds);
        for (Map map : maps) {
            System.out.println(map);
        }
    }
}

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

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

相关文章

MATLAB中Simulink的信号线

Simulink以模块为最小单位,通过信号线互相连接&#xff0c;用户可通过GUI调配每个模块的参数,且仿真的结果能够以数值和图像等形象化方式具现出来。信号线可以传递一维数据、多维数据、向量数据或矩阵数据,甚至Bus型数据。Simulink使用不同的线形表示传递不同数据类型的信号线,…

【WRF安装】WRF编译错误总结1:HDF5库包安装

目录 1 HDF5库包安装有误&#xff1a;HDF5 not set in environment. Will configure WRF for use without.HDF5的重新编译 错误原因1&#xff1a;提示 overflow 错误1. 检查系统是否缺少依赖库或工具2. 检查和更新编译器版本3. 检查 ./configure 报错信息4. 检查系统环境变量5.…

Flutter 内嵌 unity3d for android

前言&#xff1a; 最近刚整完 unity3d hybridCLR 更新代码和资源&#xff0c;我们 趁热打铁 将 Unity3D 嵌入 Flutter 应用中。实现在 Flutter 使用 Unity3D, 可以做 小游戏 大游戏&#xff1b; 之前都是 内嵌 Webview 来实现的。虽然 CocosCreator 做出来的效果也不错&#xf…

鸿蒙开发:一个轻盈的上拉下拉刷新组件

前言 老早之前开源了一个刷新组件&#xff0c;提供了很多常见的功能&#xff0c;也封装了List&#xff0c;Grid&#xff0c;WaterFlow&#xff0c;虽然功能多&#xff0c;但也冗余比较多&#xff0c;随着时间的前去&#xff0c;暴露的问题就慢慢增多&#xff0c;虽然我也提供了…

Oracle plsqldev1106 安装及TNS配置

Oracle plsqldev1106 安装及TNS配置 下载好安装包&#xff0c;直接双击安装 点击 I Agree 默认是C盘的&#xff0c;我改了D盘&#xff0c;根据自己实际情况修改 这里用默认的for current user 也可以&#xff0c;我选了for all user 点Finish&#xff0c;等待安装完成即可 …

【卷积神经网络】AlexNet实践

构建模型 模版搭建 # 定义一个AlexNet模型类def __init__(self):# 调用父类的构造函数&#xff08;如果继承自nn.Module的话&#xff09;super(AlexNet, self).__init__()# ReLU激活函数self.ReLU nn.ReLU()# 卷积层1&#xff1a;输入1个通道&#xff08;灰度图&#xff09;&a…

Linux驱动开发(13):输入子系统–按键输入实验

计算机的输入设备繁多&#xff0c;有按键、鼠标、键盘、触摸屏、游戏手柄等等&#xff0c;Linux内核为了能够将所有的输入设备进行统一的管理&#xff0c; 设计了输入子系统。为上层应用提供了统一的抽象层&#xff0c;各个输入设备的驱动程序只需上报产生的输入事件即可。 下…

计算机毕设-基于springboot的某学院兼职平台的设计与实现(附源码+lw+ppt+开题报告)

博主介绍&#xff1a;✌多个项目实战经验、多个大型网购商城开发经验、在某机构指导学员上千名、专注于本行业领域✌ 技术范围&#xff1a;Java实战项目、Python实战项目、微信小程序/安卓实战项目、爬虫大数据实战项目、Nodejs实战项目、PHP实战项目、.NET实战项目、Golang实战…

Unity3D仿星露谷物语开发3之动画系统初探

1、目标 我们希望使用已有的资源建一个动画demo&#xff0c;以此熟悉基于已有Animator/Animation资源的使用方法。 以Tree的动画系统为例&#xff0c;资源位于&#xff1a; 2、创建流程 &#xff08;1&#xff09;创建tree空对象 上面两个都是空对象。 &#xff08;2&#…

怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev

本文引用怎么禁用 vscode 中点击 go 包名时自动打开浏览器跳转到 pkg.go.dev 在 vscode 设置项中配置 gopls 的 ui.navigation.importShortcut 为 Definition 即可。 "gopls": {"ui.navigation.importShortcut": "Definition" }ui.navigation.i…

Java:183 基于SSM的高校食堂系统

项目介绍 基于SSM的食堂点餐系统 角色:管理员、用户、食堂 前台用户可以实现商品浏览&#xff0c;加入购物车&#xff0c;加入收藏&#xff0c;预定&#xff0c;选座&#xff0c;个人信息管理&#xff0c;收货信息管理&#xff0c;收藏管理&#xff0c;评论功能&#xff0c;…

[COLM 2024] V-STaR: Training Verifiers for Self-Taught Reasoners

本文是对 STaR 的改进方法&#xff0c;COLM 是 Conference On Language Models&#xff0c;大模型领域新出的会议&#xff0c;在国际上很知名&#xff0c;不过目前还没有被列入 ccf list&#xff08;新会议一般不会列入&#xff09;&#xff1b;作者来自高校、微软研究院和 Goo…

端点鉴别、安全电子邮件、TLS

文章目录 端点鉴别鉴别协议ap 1.0——发送者直接发送一个报文表明身份鉴别协议ap 2.0——ap1.0 的基础上&#xff0c;接收者对报文的来源IP地址进行鉴别鉴别协议ap 3.0——使用秘密口令&#xff0c;口令为鉴别者和被鉴别者之间共享的秘密鉴别协议ap 3.1——对秘密口令进行加密&…

电脑文件夹打不开了,能打开但是会闪退,提示“找不到iUtils.dll”是什么原因?

电脑运行时常见问题解析&#xff1a;文件夹打不开、闪退及“找不到iUtils.dll”报错 在使用电脑的过程中&#xff0c;我们可能会遇到文件夹打不开、软件闪退或系统报错等问题&#xff0c;特别是提示“找不到iUtils.dll”的报错&#xff0c;更是让人困惑不已。今天我将为大家详…

MATLAB图卷积神经网络GCN处理分子数据集节点分类研究

全文链接&#xff1a;https://tecdat.cn/?p38570 本文主要探讨了如何利用图卷积网络&#xff08;GCN&#xff09;对图中的节点进行分类。介绍了相关的数据处理、模型构建、训练及测试等环节&#xff0c;通过对分子数据集的操作实践&#xff0c;展示了完整的节点分类流程&#…

计算机网络-传输层 UDP协议

学习一个网络协议&#xff0c;主要就是学习“数据格式/报文格式” UDP的特点 UDP传输的过程类似于寄信. ⽆连接: 知道对端的IP和端⼝号就直接进⾏传输, 不需要建⽴连接; 不可靠: 没有确认机制, 没有重传机制; 如果因为⽹络故障该段⽆法发到对⽅, UDP协议层也不会给应 ⽤层返回任…

[OpenGL] Transform feedback 介绍以及使用示例

一、简介 本文介绍了 OpenGL 中 Transform Feedback 方法的基本概念和代码示例。 二、Transform Feedback 介绍 1. Transform Feedback 简介 根据 OpenGL-wiki&#xff0c;Transform Feedback 是捕获由顶点处理步骤&#xff08;vertex shader 和 geometry shader&#xff0…

拆解大语言模型RLHF中的PPO

** 拆解大语言模型RLHF中的PPO ** 参考链接&#xff1a;https://zhuanlan.zhihu.com/p/645225982 为什么大多数介绍RLHF的文章&#xff0c;一讲到PPO算法的细节就戛然而止了呢&#xff1f;要么直接略过&#xff0c;要么就只扔出一个PPO的链接。然而LLM PPO跟传统的PPO还是有…

arcGIS使用笔记(无人机tif合并、导出、去除黑边、重采样)

无人机航拍建图之后&#xff0c;通过大疆智图软件可以对所飞行的区域的进行拼图&#xff0c;但是如果需要对拼好的图再次合并&#xff0c;则需要利用到arcGIS软件。下面介绍arcGIS软件在这个过程中常用的操作。 1.导入tif文件并显示的方法&#xff1a;点击“”图标进行导入操作…

利用代理IP爬取Zillow房产数据用于数据分析

引言 最近数据分析的热度在编程社区不断攀升&#xff0c;有很多小伙伴都开始学习或从事数据采集相关的工作。然而&#xff0c;网站数据已经成为网站的核心资产&#xff0c;许多网站都会设置一系列很复杂的防范措施&#xff0c;阻止外部人员随意采集其数据。为了解决这个问题&a…