Canal的基本使用

参考 https://www.51cto.com/article/626708.html

安装Mysql 8

1
2
3
4
5
6
7
8
9
10
11
12
13
docker pull mysql/mysql-server:latest
docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=qxiu2022 -d mysql/mysql-server

进入mysql docker容器
docker exec -it 123456 /bin/sh
GRANT ALL PRIVILEGES ON *.* TO 'abc'@'%';
#设置可以远程连接
ALTER USER 'abc'@'%' IDENTIFIED WITH mysql_native_password BY 'abc123';
flush priviles;

#修改容器的系统时间
docker cp /usr/share/zoneinfo/Asia/Shanghai docker_container_id:/etc/localtime
docker restart docker_container_id

Canal-Server

通过docker镜像的方式启动Cannal-Server还有点问题,下边通过下载 canal-canal.deployer-1.1.7-SNAPSHOT.tar.gz ,然后通过命令行的方式启动

Read More

Elasticsearch跨集群备份

概述

目前7.0以上版本跨集群备份的方式有很多,例如elasticsearch-dump,reindex,snapshot,logstash。

方案对比

方案 elasticsearch-dump reindex snapshot logstash
基本原理 逻辑备份,类似mysqldump将数据一条一条导出后再执行导入 reindex 是 Elasticsearch 提供的一个 API 接口,可以把数据从一个集群迁移到另外一个集群 从源集群通过Snapshot API 创建数据快照,然后在目标集群中进行恢复 从一个集群中读取数据然后写入到另一个集群
网络要求 集群间互导需要网络互通,先导出文件再通过文件导入集群则不需要网络互通 网络需要互通 无网络互通要求 网络需要互通
迁移速度 一般
适合场景 适用于数据量小的场景 适用于数据量大,在线迁移数据的场景 适用于数据量大,接受离线数据迁移的场景 适用于数据量一般,近实时数据传输
配置复杂度 中等 简单 复杂 中等

Read More

hadoop集群RM和ZK异常的解决

修改了Flume的配置,然后需要将有过期配置的服务重启了一下,然后集群上有些服务就异常了。

Yarn服务异常: 2个ResourceManager同时处于standby状态

首先yarn服务异常,2个ResourceManager (分别为hadoop101和hadoop102) 同时处于standby状态。然后根据stackoverflow上的解释,使用如下命令

1
yarn resourcemanager -format-state-store

在hadoop101上以hdfs用户执行,过了1分钟,问题仍旧没有解决,2个ResourceManager仍然同时处于standby状态。

Read More

Parse_url函数 (Spark SQL)

from https://docs.microsoft.com/zh-cn/azure/databricks/sql/language-manual/functions/parse_url

从 url 中提取一部分。

语法

1
parse_url(url, partToExtract [, key] )

参数

  • url:一个 STRING 表达式。
  • partToExpract:一个 STRING 表达式。
  • key:一个 STRING 表达式。

    返回

    字符串。

partToExtract 必须是以下各项之一:

  • ‘HOST’
  • ‘PATH’
  • ‘QUERY’
  • ‘REF’
  • ‘PROTOCOL’
  • ‘FILE’
  • ‘AUTHORITY’
  • ‘USERINFO’
    key 区分大小写。

如果未找到请求的 partToExtract 或 key,则返回 NULL。

示例

SQL

1
2
3
4
5
6
SELECT parse_url('http://spark.apache.org/path?query=1', 'HOST');
spark.apache.org
SELECT parse_url('http://spark.apache.org/path?query=1', 'QUERY');
query=1
SELECT parse_url('http://spark.apache.org/path?query=1', 'QUERY', 'query');
1

Clickouse新特性调研 Release v21.11, 2021-11-09

向后兼容变化

  • 改变了SQL/JSON函数中json_path和json参数的位置。
  • 移除了MergeTree表的write_final_mark设置,这个值总是为true,新的版本会兼容所有的表,不需要其他的设置。
  • 移除了bayesAB函数。
  • 如果你已经开始使用clickhouse-keeper 特性,可以看一下这条内容。现在ClickHouse Keeper快照默认使用ZSTD编码的方式进行压缩,而不再是LZ4块压缩,可以通过compress_snapshots_with_zstd_format 设置来关闭此特性(在所有的集群副本上保持设置一致)。一般都是向后兼容的,但是也有可能出现不兼容的情况,当一个新节点向不能读取ZSTD格式快照的旧节点发送快照的时候(在恢复的时候可能会发生)。

Read More

Tornado 报错TypeError: Object of Type Datetime Is Not JSON Serializable

在使用Tornado从mysql查询出来数据,然后返回通过self.write(result)给前端,但是如果数据中包含日期时间类型的字段,比如timestamp类型,就会报TypeError: Object of Type Datetime Is Not JSON Serializable错误。

这个问题其实很好解决,看tornado的源码就可以知道,self.write()属于web.py中的方法,这个方法中有一段如下的代码

1
2
3
if isinstance(chunk, dict):
chunk = escape.json_encode(chunk)
self.set_header("Content-Type", "application/json; charset=UTF-8")

其中escape.json_encode(chunk)方法中调用了
json.dumps(value).replace("</", "<\\/")

这就知道如何做了,改变json.dumps对时间日期字段的解析方式就可以了,先定义一个解码类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import json
from decimal import Decimal
from datetime import datetime,date

class DateEncoder(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime):
return o.strftime('%Y-%m-%d %H:%M:%S')
elif isinstance(o, date):
return o.strftime("%Y-%m-%d")
elif isinstance(o, Decimal):
return float(o)
else:
return json.JSONEncoder.default(self, o)

然后将 def json_encode(value: Any) -> str: 方法的实现改为

1
return json.dumps(value,cls=DateEncoder).replace("</", "<\\/")

就可以了,重启一下服务,就可以了。

这种方式看似可以,实则有个大坑,会导致很多接口调用参数传递失败,还是不建议这么做,如果真的要修改字符字段的类型,在程序中修改吧。

Axios CORS跨域问题解决

前端通过使用axios请求后台服务,默认是不带cookie上报的,要想带上,需要进行如下设置:

1
axios.defaults.withCredentials = true

然后后端服务也要做些调整,比如Tornado需要设置

1
2
self.set_header("Access-Control-Allow-Credentials", "true")
self.set_header("Access-Control-Allow-Origin",origin)

如果不想在程序中设置的话,可以调整一下nginx的配置,比如某个location下增加如下配置:

1
2
3
4
5
6
add_header 'Access-Control-Allow-Credentials' "true";
add_header 'Access-Control-Allow-Origin' "$http_origin";
add_header 'Access-Control-Allow-Headers' '*';
add_header 'Access-Control-Max-Age' 1000;
add_header 'Access-Control-Allow-Methods' 'POST, GET, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'authorization, Authorization, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, X-Requested-By, Access-Control-Allow-Methods';