当前位置: 首页 > news >正文

深圳做网站公e福州官方网站

深圳做网站公,e福州官方网站,个人内网网站建设,腾讯云服务器网站域名备案引言 Apache Doris 作为一款 OLAP 实时数据仓库#xff0c;在越来越多的中大型企业中逐步占据着主数仓这样的重要位置#xff0c;主数仓不同于 OLAP 查询引擎的场景定位#xff0c;对于数据的灾备恢复机制有比较高的要求#xff0c;本篇就让我们全面的介绍和示范如何利用这…引言 Apache Doris 作为一款 OLAP 实时数据仓库在越来越多的中大型企业中逐步占据着主数仓这样的重要位置主数仓不同于 OLAP 查询引擎的场景定位对于数据的灾备恢复机制有比较高的要求本篇就让我们全面的介绍和示范如何利用这些特性能力构建集群数据的灾备恢复机制。 这里恢复备份机制除 Backup 和 Restore 语法以外所有可以导出后再导入的方式都可被视为备份恢复的特性能力。 本文中所有的机制我都已挨个搭建环境测试了一遍并给了示例可放心使用 话不多说上干货~ 更好的阅读体验可前往原文阅读全面介绍 Apache Doris 数据灾备恢复机制及使用示例 | 巨人肩膀 机制概览 Apache Doris 的灾备恢复机制非常丰富可满足各式各样数据容灾备份的应用场景以下是所有机制的概览表。 特性名称适用场景存储位置吞吐速度MySQL Dump/Source小数据量数据以及表结构语句导出MySQL Client 节点指定位置结果集数据量较小数千条速度较快Export/Import大批量原始数据导出导入HDFS、支持S3协议的对象存储、本地文件系统异步任务速度中等Outfile导出数据需要经过复杂计算逻辑的如过滤、聚合、关联等HDFS、支持S3协议的对象存储、本地文件系统原始非压缩格式的数据导出需要做行列转换速度一般ADBC数据科学大规模吞吐场景代码指定即可Pandas等高速数据吞吐场景无需行列转换相较传统JDBC快数十倍Backup/Restore原生备份和恢复HDFS、支持S3协议的对象存储直接拷贝压缩后的数据文件备份速度最快冷热分层冷热数据不同存储介质SSD、HDD、HDFS、支持S3协议的对象存储数据自动Rebalance速度取决于网卡带宽、介质IOPS、Balance线程数CCR跨集群近实时数据同步主从集群本地盘介质同步速度主要取决于网卡带宽和网络带宽 在导出的三种机制 MySQL Dump、Export、OutFile 中分别适用于不同的场景内三种导出方式的异同点如下 SELECT INTO OUTFILEEXPORTMySQL DUMP同步/异步同步异步提交 EXPORT 任务后通过 SHOW EXPORT 命令查看任务进度同步支持任意 SQL支持不支持不支持导出指定分区支持支持不支持导出指定 Tablets支持不支持不支持并发导出支持且并发高但取决于 SQL 语句是否有 ORDER BY 等需要单机处理的算子支持且并发高支持 Tablet 粒度的并发导出不支持只能单线程导出支持导出的数据格式Parquet、ORC、CSVParquet、ORC、CSVMySQL Dump 专有格式是否支持导出外表支持部分支持不支持是否支持导出 View支持支持支持支持的导出位置S3、HDFS、LOCALS3、HDFS、LOCALLOCAL 示例演示 1、MySQL Dump/Source 适用场景 数据量在数万条以内或更小的数据量比如BI使用者将查询以后的报表结果集数据导出为CSV、或者将表结构语句导出至指定存储目录等场景比较适用不可用于大规模数据导出和导入。 使用示例 ①Dump 常见使用语法 # 1. 导出指定数据库中的指定表 mysqldump -h ${FE_IP}-P ${FE_QUERY_PORT}-u ${USERNAME}-p ${PASSWORD}--no-tablespaces --databases ${DATABASE_NAME} --tables ${TABLES_NAME}# 2. 仅导出指定数据库中的指定表结构 mysqldump -h ${FE_IP}-P ${FE_QUERY_PORT}-u ${USERNAME}-p ${PASSWORD}--no-tablespaces --databases ${DATABASE_NAME} --tables ${TABLES_NAME} --no-data# 3. 导出多个数据库中所有表数据结构 mysqldump -h ${FE_IP}-P ${FE_QUERY_PORT}-u ${USERNAME}-p ${PASSWORD}--no-tablespaces --databases ${DATABASE_NAME_1} ${DATABASE_NAME_2} ${DATABASE_NAME_3} --no-data# 4. 导出所有数据库的表结构 mysqldump -h ${FE_IP}-P ${FE_QUERY_PORT}-u ${USERNAME}-p ${PASSWORD}--no-tablespaces --all-databases --no-data# 将结果导出至指定位置以示例2为例 mysqldump -h ${FE_IP}-P ${FE_QUERY_PORT}-u ${USERNAME}-p ${PASSWORD}--no-tablespaces --databases ${DATABASE_NAME} --tables ${TABLES_NAME} --no-data ${RESULT_FILE_PATH} 参数说明FE_IPDoris 的 FE 节点内网 IPFE_QUERY_PORT默认值为9030USERNAMEDoris 用户名PASSWORDDoris 用户密码DATABASE_NAME数据库名TABLES_NAME数据表名RESULT_FILE_PATH导出文件路径同时请注意由于 Doris 中没有 MySQL 里的 tablespace 概念因此在使用 MySQL Dump 时要加上 --no-tablespaces 参数! ②Source 使用语法 1.登入 Doris FE Client mysql -u ${USERNAME} -P ${FE_QUERY_PORT} -h ${FE_HOST_IP} -p ${PASSWORD} 2.使用 Source 命令完成导入 source ${SQL_FILE_PATH} 2、Export/Import 适用场景 将大批量数据导出至远端存储系统中如HDFS、支持S3协议的对象存储、本地文件系统等这类导出会先将存储在 Doris 的压缩数据进行解压缩和列转行然后再根据导出时候的参数定义转为指定的数据类型格式。 所以导出的数据量虽然可以相对较大但是速度往往没有想象中的那么快适合大数据量的单表导出、仅需简单的过滤条件和需要异步提交任务的场景。 底层导出函数调用为 Outfile。 使用示例 标准语法 EXPORT TABLE table_name [PARTITION (p1[,p2])] [WHERE] TO export_path [opt_properties] WITH BROKER/S3/HDFS [broker_properties]; 详细参数说明请参照 https://doris.apache.org/zh-CN/docs/dev/sql-manual/sql-statements/Data-Manipulation-Statements/Manipulation/EXPORT ①导出至本地文件系统 导出至本地文件系统必须在 fe.conf 配置文件中配置参数 enable_outfile_to_localtrue重启 FE 后生效。 EXPORT TABLE ${TABLE_NAME} TO ${LOCAL_FILE_PATH} 请注意LOCAL_FILE_PATH 有以下限制1. 格式前缀为 file://2. 仅可以指定至文件夹目录级3. 指定的文件夹目录必须为多个 BE 节点共有目录如 /root/、/home 等否则无法创建对应文件 示例 1.导出 demo 库中的 part 表且放置在 /root 目录下 EXPORT TABLE demo.part TO file:///root/; 2.查看异步导出任务 SHOW EXPORT\G; 3.根据指定 URL 查看导出文件数据 # 切换登录至导出 BE 节点 ssh 192.168.31.163 # 查看导出文件 cat /root/7acf8d7494654119-bae09df41ccf23c9_0.csv 若需要在导出过程中进行过滤、指定压缩格式等定制化能力请参照本小节前的 EXPORT 命令说明链接内容这里不做赘述。 ②导出至 S3 对象存储 EXPORT TABLE ssb.port TOs3://${BUCKET}/${S3_PATH} WITH s3 ( s3.endpoint${S3_HTTP_API}, s3.region${S3_REGION}, s3.access_key${AK}, s3.secret_key${SK} ); 若使用 MinIO参数需要注意以下几点 1. 需要添加 use_path_style true 配置项 2. S3_REGION 值默认为 us-east-1 3. AK、SK 可以使用 USERNAME PASSOWORD也可以使用在 MinIO 内创建的 AK、SK 示例 导出数据至 MinIO 导出后 MinIO Bucket 使用情况 ③导出至 HDFS EXPORT TABLE ${TABLE_NAME} TO hdfs://${NAMENODE_IP}:{PORT}/${PATH} with HDFS ( fs.defaultFShdfs://${NAMENODE_IP}:{PORT}, hadoop.username ${HADOOP_USERNAME} ); 示例 1.创建导出任务 2.导出任务执行成功 3、Select Into Outfile 适用场景 Select Into Outfile 实则为 Export 的底层执行函数作为同步导出任务可执行较为复杂的逻辑查询后的结果集输出方式。 使用示例 标准语法 query_stmt INTO OUTFILE file_path [FORMAT_AS] [PROPERTIES] 更详细的参数说明请翻阅官方文档 https://doris.apache.org/zh-CN/docs/dev/data-operate/export/outfile 以 SSB 测试集的标准查询 Q2.2 作为查询语句以 limit 100 作为条数限制SQL 如下 SELECT SUM(lo_revenue), d_year, p_brand FROM lineorder, dates, part, supplier WHERE lo_orderdate d_datekey AND lo_partkey p_partkey AND lo_suppkey s_suppkey AND p_brand BETWEENMFGR#2221ANDMFGR#2228 AND s_region ASIA GROUPBY d_year, p_brand ORDERBY d_year, p_brand; ①导出至本地文件系统示例 SELECT SUM(lo_revenue), d_year, p_brand FROM lineorder, dates, part, supplier WHERE lo_orderdate d_datekey AND lo_partkey p_partkey AND lo_suppkey s_suppkey AND p_brand BETWEENMFGR#2221ANDMFGR#2228 AND s_region ASIA GROUPBY d_year, p_brand ORDERBY d_year, p_brand LIMIT 100 INTO OUTFILE s3://doris/ PROPERTIES( use_path_styletrue, s3.endpointhttp://192.168.31.198:19000, s3.regionus-east-1, s3.access_keyminioadmin, s3.secret_keyminioadmin ); 1.执行导出任务 2.导出节点文件查看 ②导出至 S3 对象存储示例 SELECT SUM(lo_revenue), d_year, p_brand FROM lineorder, dates, part, supplier WHERE lo_orderdate d_datekey AND lo_partkey p_partkey AND lo_suppkey s_suppkey AND p_brand BETWEENMFGR#2221ANDMFGR#2228 AND s_region ASIA GROUPBY d_year, p_brand ORDERBY d_year, p_brand LIMIT 100 INTO OUTFILE hdfs://192.168.31.198:8020/doris/ PROPERTIES( fs.defaultFShdfs://192.168.31.198:8020, hadoop.usernamehadoop ); 1.执行导出任务 2.对象存储上的记录 ③导出至 HDFS 示例 SELECT SUM(lo_revenue), d_year, p_brandFROM lineorder, dates, part, supplierWHERE    lo_orderdate  d_datekeyAND lo_partkey  p_partkeyAND lo_suppkey  s_suppkeyAND p_brand BETWEENMFGR#2221ANDMFGR#2228AND s_region ASIAGROUPBY d_year, p_brandORDERBY d_year, p_brandLIMIT 100INTO OUTFILE hdfs://192.168.31.198:8020/doris/PROPERTIES(fs.defaultFShdfs://192.168.31.198:8020,hadoop.usernamehadoop); 1.使用 SelectDB Web UI 执行命令 2.HDFS 文件系统界面查看是否上传成功 3.查看文件内容是否正确 4、ADBC 适用场景 ADBC 即 Arrow DataBase ConnectivityDoris 基于 Arrow Flight SQL 协议实现了高速数据链路支持多种语言使用 SQL 从 Doris 高速读取大批量数据。 使用 ADBC 协议可从 Doris 加载大批量数据到其他组件如 Python/Java/Spark/Flink可以使用基于 Arrow Flight SQL 的 ADBC/JDBC 替代过去的 JDBC/PyMySQL/Pandas 来获得更高的读取性能这在数据科学、数据湖分析等场景中经常遇到。 JDBC与ADBC数据流转原理简图 这里需要注意的是ADBC不仅可以用于读还可以用于其他常规语法操作比如查询、写入。 使用示例 ①Python 代码引用 ADBC Driver 安装步骤详见官网说明https://doris.apache.org/zh-CN/docs/dev/db-connect/arrow-flight-sql-connect#adbc-driver这里不做详细赘述 # Import 引入 import adbc_driver_manager import adbc_driver_flightsql.dbapi as flight_sql# 执行查询 cursor.execute(select k5, sum(k1), count(1), avg(k3) from arrow_flight_sql_test group by k5;) print(cursor.fetchallarrow().to_pandas()) Java 代码引用 POM 依赖引入同上所述不做详细介绍可移步至官网了解 ②ADBC 方式链接使用 // 1. new driver finalBufferAllocatorallocatornewRootAllocator(); FlightSqlDriverdrivernewFlightSqlDriver(allocator); MapString,Object parameters newHashMap(); AdbcDriver.PARAM_URI.set(parameters,Location.forGrpcInsecure(0.0.0.0,9090).getUri().toString()); AdbcDriver.PARAM_USERNAME.set(parameters,root); AdbcDriver.PARAM_PASSWORD.set(parameters,); AdbcDatabaseadbcDatabase driver.open(parameters);// 2. new connection AdbcConnectionconnection adbcDatabase.connect(); AdbcStatementstmt connection.createStatement();// 3. execute query stmt.setSqlQuery(select * from information_schema.tables;); QueryResultqueryResult stmt.executeQuery(); ArrowReaderreader queryResult.getReader();// 4. load result ListString result newArrayList(); while(reader.loadNextBatch()){ VectorSchemaRootroot reader.getVectorSchemaRoot(); StringtsvString root.contentToTSVString(); result.add(tsvString); } System.out.printf(batchs %d\n, result.size());// 5. close reader.close(); queryResult.close(); stmt.close(); connection.close(); ③JDBC 方式链接使用 final MapString,Object parameters newHashMap(); AdbcDriver.PARAM_URI.set( parameters,jdbc:arrow-flight-sql://0.0.0.0:9090?useServerPrepStmtsfalsecachePrepStmtstrueuseSSLfalseuseEncryptionfalse); AdbcDriver.PARAM_USERNAME.set(parameters,root); AdbcDriver.PARAM_PASSWORD.set(parameters,); try( BufferAllocatorallocatornewRootAllocator(); AdbcDatabasedbnewJdbcDriver(allocator).open(parameters); AdbcConnectionconnection db.connect(); AdbcStatementstmt connection.createStatement() ){ stmt.setSqlQuery(select * from information_schema.tables;); AdbcStatement.QueryResultqueryResult stmt.executeQuery(); ArrowReaderreader queryResult.getReader(); ListString result newArrayList(); while(reader.loadNextBatch()){ VectorSchemaRootroot reader.getVectorSchemaRoot(); StringtsvString root.contentToTSVString(); result.add(tsvString); } longetimeSystem.currentTimeMillis(); System.out.printf(batchs %d\n, result.size());reader.close(); queryResult.close(); stmt.close(); }catch(Exception e){ e.printStackTrace(); } 性能对比 从实际测试对比来看ADBC在查询数据吞吐方面比传统 JDBC 能力超百倍左右所以在诸如 Pandas 等科学计算框架应用方面有非常明显的效率提升。 5、Backup/Restore 适用场景 正宗的库表级的数据备份/恢复能力可选择整库备份也可选择某些表进行备份粒度有库、表、分区三个级别。 其备份原理是将已有的库表 Tablet 整理出一份完整、可靠的单副本然后拷贝至 HDFS 或 S3 之上中间不处理任何数据转换所以速度是最快的。 同时增量备份能力现在也在研发阶段了。 使用示例 ①备份至 HDFS 1.创建 HDFS repository CREATE REPOSITORY hdfs_repo WITH hdfs ON LOCATION hdfs://192.168.31.198:8020/doris-repo PROPERTIES ( fs.defaultFShdfs://192.168.31.198:8020, hadoop.usernameuser, dfs.replication1 ); 2.备份单表至 HDFS 标准语法 BACKUP SNAPSHOT [db_name].{snapshot_name} TOrepository_name [ON|EXCLUDE]( table_name[PARTITION(p1,...)], ... ) PROPERTIES (keyvalue, ...); 备份 ssb 仓库的 lineorder 明细表的 p1 分区 BACKUP SNAPSHOT ssb.back01 TO hdfs_repo ON ( lineorder PARTITION(p1) ); 3.查看已备份数据 ②备份至 S3 1.创建 S3 Repository CREATE REPOSITORY minio_repo WITH S3 ON LOCATION s3://doris-repo PROPERTIES ( use_path_styletrue, s3.endpointhttp://192.168.31.198:19000, s3.regionus-east-1, s3.access_keyminioadmin, s3.secret_keyminioadmin ); 2.备份 ssb 仓库的 supplier 整表 BACKUP SNAPSHOT ssb.back02 TO minio_repo ON ( supplier ); 3.查看已备份的数据 这里需要注意的是同一数据库下只能有一个正在执行的 BACKUP 或 RESTORE 任务 ③从 HDFS 还原快照 1.删除 ssb 仓库的 lineorder 明细表的 p1 分区 DELETE FROM lineorder PARTITION p1 WHERE lo_orderkey is not null; SELECT COUNT(*) FROM lineorder PARTITION p1; 2.从 HDFS 恢复数据 标准语法 RESTORE SNAPSHOT [db_name].{snapshot_name} FROMrepository_name [ON|EXCLUDE]( table_name[PARTITION(p1,...)][AStbl_alias], ... ) PROPERTIES (keyvalue, ...); 查看快照版本的时间 SHOW SNAPSHOT ON repo; 恢复 HDFS 数据 RESTORE SNAPSHOT ssb.back01 FROMhdfs_repo ON( lineorderPARTITION(p1) ) PROPERTIES( backup_timestamp2024-08-07-19-36-31, replication_num1 ); 3.查看恢复结果 SELECT COUNT(*) FROM lineorder PARTITION p1; ④从 S3 还原快照 1.删除 supplier 表数据 DELETE FROM supplier WHERE s_suppkey is not null; SELECT COUNT(*) FROM supplier; 2.从 S3 备份恢复 supplier 表数据 RESTORE SNAPSHOT ssb.back02 FROMminio_repo ON( supplier ) PROPERTIES( backup_timestamp2024-08-07-20-18-09, replication_num1 ); 查看快照时间 3.查看恢复结果 SELECT COUNT(*) FROM supplier; 6、冷热分层 适用场景 在存算一体架构下希望将存储周期比较长的数据冷备至存储成本较低的介质中比如某明细表日增1TB业务查询经常会用到30天内的数据为了保证查询效率这些热数据用 SSD 存储介质来存储30天以前的数据希望用更便宜的存储介质来存储以此降低整体架构成本。 这里需要说明的一点是冷热分层不会改变查询使用习惯。 冷热数据是通过表配置来决定啥时候进行冷备以及冷备到什么位置。 查询的数据会自动完成迁移不需要任何人为干预。 使用示例 冷备至HDFS 1.创建 hdfs_resource Resource 资源 CREATE RESOURCE hdfs_resource PROPERTIES ( typehdfs, fs.defaultFShdfs://192.168.31.198:8020, hadoop.usernamehadoop, dfs.namenode.rpc-address192.168.31.198:8020, dfs.replication1 ); 2.创建冷备策略设置冷备资源为 HDFS_RESOURCE冷备时间为存储后 60 秒。 CREATE STORAGE POLICY hdfs_policy PROPERTIES ( storage_resource hdfs_resource, cooldown_ttl 60 ) 3.创建 customer_hdfs_cold 表表结构使用 customer 的表结构冷备策略设置为 hdfs_policy。 CREATE TABLE customer_hdfs_cold( c_custkeyINTNOTNULL, c_nameVARCHAR(26)NOTNULL, c_addressVARCHAR(41)NOTNULL, c_cityVARCHAR(11)NOTNULL, c_nationVARCHAR(16)NOTNULL, c_regionVARCHAR(13)NOTNULL, c_phoneVARCHAR(16)NOTNULL, c_mktsegmentVARCHAR(11)NOTNULL ) ENGINE OLAP DUPLICATE KEY(c_custkey) COMMENT OLAP DISTRIBUTED BY HASH(c_custkey) BUCKETS 12 PROPERTIES ( replication_allocationtag.location.default: 1, storage_policyhdfs_policy ); 4.插入customer 的数据至 customer_hdfs_cold 表中60秒后观察数据冷备情况。 INSERT INTO customer_hdfs_cold SELECT * FROM customer; 5.查看冷备数据情况 show tablets from customer_hdfs_cold; 执行查询 SELECT * FROM customer_hdfs_cold LIMIT 10; 6.查看远端存储情况 冷备至 S3 1.创建 remote_s3 Resource 资源 CREATE RESOURCE remote_s3 PROPERTIES ( types3, use_path_styletrue, s3.endpointhttp://192.168.31.198:19000, s3.regionus-east-1, s3.access_keyminioadmin, s3.secret_keyminioadmin, -- required by cooldown s3.root.path/cold, s3.bucketdoris-repo ); 2.创建冷备策略设置冷备资源为 S3_RESOURCE冷备时间为存储后 60 秒。 CREATE STORAGE POLICY s3_policy PROPERTIES ( storage_resource remote_s3, cooldown_ttl 60 ) 3.创建 customer_s3_cold 表表结构使用 customer 的表结构冷备策略设置为 hdfs_policy。 CREATE TABLEcustomer_s3_cold(c_custkeyINTNOTNULL,c_nameVARCHAR(26)NOTNULL,c_addressVARCHAR(41)NOTNULL,c_cityVARCHAR(11)NOTNULL,c_nationVARCHAR(16)NOTNULL,c_regionVARCHAR(13)NOTNULL,c_phoneVARCHAR(16)NOTNULL,c_mktsegmentVARCHAR(11)NOTNULL) ENGINE  OLAP DUPLICATE KEY(c_custkey) COMMENT OLAP DISTRIBUTED BY HASH(c_custkey) BUCKETS 12 PROPERTIES (replication_allocationtag.location.default: 1,storage_policys3_policy     ); 4.插入customer 的数据至 customer_s3_cold 表中60秒后观察数据冷备情况。 INSERT INTO customer_s3_cold   SELECT * FROM customer; 5.查看冷备数据情况 show tablets from customer_s3_cold; 执行查询 SELECT * FROM customer_hdfs_cold LIMIT 10; 6.查看远端存储情况 7、CCR 适用场景 CCR(Cross Cluster Replication) 是跨集群数据同步能够在库/表级别将源集群的数据变更同步到目标集群可用于在线服务的数据可用性、隔离在离线负载、建设两地三中心。 使用示例 使用非常简单只需把Syncers服务启动给他发一个命令剩下的交个Syncers完成就行。 1.1. 部署源doris集群 2.2. 部署目标doris集群 3.3. 首先源集群和目标集群都需要打开binlog在源集群和目标集群的fe.conf和be.conf中配置如下信息这是大前提 enable_feature_binlogtrue 1.1. 部署 syncers 获取CCR包 # 联系 SelectDB 同学即可免费获取 CCR 二进制包 2.启动和停止syncer # 启动 cd bin sh start_syncer.sh --daemon # 停止 sh stop_syncer.sh 3.打开源集群中同步库/表的 binlog -- 如果是整库同步可以执行如下脚本使得该库下面所有的表都要打开binlog.enable vim shell/enable_db_binlog.sh 修改源集群的host、port、user、password、db-- 如果是单表同步则只需要打开table的binlog.enable在源集群上执行 ALTER TABLE enable_binlog SET (binlog.enable true); 4.向syncer发起同步任务 curl -X POST -H Content-Type: application/json -d { name: ccr_test, src: { host: localhost, port: 9030, thrift_port: 9020, user: root, password: , database: your_db_name, table: your_table_name }, dest: { host: localhost, port: 9030, thrift_port: 9020, user: root, password: , database: your_db_name, table: your_table_name } } http://127.0.0.1:9190/create_ccr 同步任务的参数说明 name: CCR同步任务的名称唯一即可 host、port对应集群master FE的host和mysql(jdbc) 的端口 user、passwordsyncer以何种身份去开启事务、拉取数据等 database、table 如果是db级别的同步则填入your_db_nameyour_table_name为空 如果是表级别同步则需要填入your_db_nameyour_table_name 向syncer发起同步任务中的name只能使用一次 小结 本篇延续了个人的实操习惯边搭环境边写文档所以速度比较慢基本上消耗了十天左右的工作后休息时间。 不过返回来在从头阅读时感觉整体篇幅还是过于长了其实每个机制都可以掰开揉碎了讲比如底层机制比如一些局限性和适用性本篇文章希望能起一个提纲要领的引子作用在各位看官老爷看完后某天希望使用 Doris 完成各种场景下的备份恢复的话大可收藏来翻阅。 看到这里就别吝啬各位的点赞和在看以及评论转发啦 每次良好的数据都是下次努力更新的绝对动力
http://www.tj-hxxt.cn/news/226219.html

相关文章:

  • 高性能网站建设 下载吕梁网站建设公司
  • 哈尔滨自助建站系统中国建筑网官网查询施工员证
  • 网站建设及网络维护合同精准客源推广引流
  • 免费网站域名申请茶叶网站建设方案
  • c 企业网站开发aso榜单优化
  • 深圳哪些公司做网站python做网站需要什么
  • 简单的个人网站html网站开发需要什么费用
  • 保定免费建站seo关键词排名优化如何
  • 哪里可以接一些网站项目做邢台短视频推广
  • 电商网站建设与开发期末考试公司部门职责与岗位职责大全范本
  • 飞创网站建设建设网站dns如何设置
  • 网站建设丨选择金手指排名15简述seo的优化流程
  • 网站标题flash网站关键词检测
  • 网站维护需要哪些知识vs做asp网站
  • 网站建设合并但与那个杭州做网站好的公司排名
  • 怎么浏览英文网站绍兴本地网站建设
  • 揭阳专业网站制作公司工程公司有哪些职位
  • 网站建设宣传文案艾宗建设计公司网站
  • 小说网页网站建设如何用wordpress查看搭建的站点
  • 哪些网做网站比较好网页设计论文题目什么样的好写
  • 云南网站建设定做网站建设的发展
  • kuake自助建站系统官网企业管理10大系统
  • 章丘营销型网站建设wordpress 加入引导页
  • 数字域名做网站企业网站设计方式
  • 做网站新手流程株洲在线网站的目标客户
  • 小清新博客网站门户类网站前台
  • 开发网站如何选需要怎么做网站源代码
  • 申请网站空间就是申请域名宁波市住房和城乡建设局网站
  • seo入门黑帽培训教程河北网站优化
  • 网站建设合集外贸流程全步骤流程图