获取建表语句:

1
SHOW CREATE TABLE table_name

获取表结构:

1
2
3
# DESC 是 DESCRIBE 的缩写
DESC table_name
SHOW COLUMNS FROM table_name

筛选字段:

1
2
3
# field_name 可以包括通配符
DESC table_name "field_name"
SHOW COLUMNS FROM table_name LIKE "field_name"

另外,经过测试,SHOW COLUMNS FROM 语句除了可以使用 LIKE 关键字,还可以使用 WHERE 子句,但 DESCRIBE 语句不支持。

这个问题网上众说纷纭,有的答案不完全正确,有的答案没有解释清楚。

这里先说我认为正确的答案:

如果学习过 cpp 的话,说传值或者传引用都不准确,直接理解为传地址(指针)就好了,不管可变对象还是不可变对象都是传地址。

详细解释,在函数内:

  • 对传入参数的赋值操作,是创建新的对象,可以理解为声明新的变量,自然不会影响到函数外变量
  • 对传入参数所指对象的修改操作,如 list 的 append,由于是指针,因此修改了函数外变量,注意在 python 中不可变对象类型是不包含可以修改对象的接口的,即便有些接口看起来像修改了,也是返回了新的对象,而不是对原对象的修改,即不是原地修改
  • 这也解释了当传递复杂类型参数:a = tuple(b = list(), 1, 2, 3) 这种数据时,虽然 a 是不可变类型,但通过 a[0].append() 依然可以成功修改 b,也意味着修改了 a,且函数外变量会也会被修改的原因

综上所述,也可以理解为传引用,但要注意,这里的“引用”二字是广义的,不要狭义得理解为是 cpp 中的引用,两者是不同的,在 cpp 中对函数内传入的引用参数执行赋值操作,将会影响到函数外的变量。

先说环境:
两节点 k8s 集群,一台 master,k8s 版本为 1.18.1,所使用的 dashboard 版本为 v2.0.0-rc7

dashboard 安装方法直接按照官网所说的执行即可:

1
2
kubectl delete ns kubernetes-dashboard
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc7/aio/deploy/recommended.yaml

现在 dashboard 已经部署好了,问题是如何访问 dashboard 服务,首先新版的 dashboard 将默认权限控制到了最小,只够 dashboard 部署,要想正常访问 dashboard 服务需要按照下面这个官方文档对其进行授权和创建管理员账户:
https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md

如果不想细看,可以直接将如下代码保存至 dashboard-admin.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard

然后执行:

1
kubectl apply -f dashboard-admin.yaml

接着获取创建的 admin 账户的 token:

1
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

拿到 token 开始将 dashboard 服务暴露出来,有两种方式:

阅读全文 »

由于在 bashrc 中配置了自动 run/attach tmux,因此在 vscode 内启动终端时也会找 tmux,如果想避免这种情况或者类似的情况可以通过修改 vscode 的配置文件,添加自定义环境变量,然后在 bashrc 里进行判断,比如在 vscode 的配置文件中添加如下内容:

1
2
3
4
5
6
7
// NOTE: 在 deepin linux bash 下经过测试发现,不能使用 VSCODE_ 开头的名字作为变量,否则无效
"terminal.integrated.env.linux": {
"IS_VSCODE_INTEGRATED_TERMINAL": "1"
},
"terminal.integrated.env.osx": {
"IS_VSCODE_INTEGRATED_TERMINAL": "1"
},

表示在 linux/osx 下的 vscode 里,为终端设置值为 1 的环境变量: IS_VSCODE_INTEGRATED_TERMINAL

然后在 bashrc 文件中进行检测,如果存在此变量则不启动 tmux:

1
2
3
4
5
6
7
if [[ -z $IS_VSCODE_INTEGRATED_TERMINAL ]]; then
which tmux > /dev/null 2>&1\
&& [[ -z "$TMUX" ]]\
&& { if ! tmux a; then exec tmux; fi; }
else
echo "-> disabled tmux <-"
fi

首先:

1
2
3
4
5
6
# 官方仓库:
https://github.com/kubernetes/minikube
# 官方安装教程:
https://kubernetes.io/docs/tasks/tools/install-minikube/
# 官方使用教程:
https://kubernetes.io/zh/docs/setup/learning-environment/minikube/

安装过程比较省心,没出什么意外就成功了,在执行: minikube start 时一直报错,无法成功启动环境,主要原因自然还是因为 GFW 的问题。

可是我挂上代理(proxychains 命令无效,我用的 http_proxy && https_proxy)依然起不来,使用如下命令可以将日志打印到终端上:

1
minikube start --logtostderr

经过分析后发现失败原因是因为有一个 docker 镜像 gcr.io/k8s-minikube/kicbase:v0.0.8 pull 不下来:

1
2
3
4
5
6
7
8
9
10
11
Pulling base image ...
cache.go:104] Beginning downloading kic artifacts
preload.go:81] Checking if preload exists for k8s version v1.18.0 and runtime docker
preload.go:97] Found local preload: /home/ri/.minikube/cache/preloaded-tarball/preloaded-images-k8s-v2-v1.18.0-docker-overlay2-amd64.tar.lz4
cache.go:46] Caching tarball of preloaded images
preload.go:123] Found /home/ri/.minikube/cache/preloaded-tarball/preloaded-images-k8s-v2-v1.18.0-docker-overlay2-amd64.tar.lz4 in cache, skipping download
cache.go:49] Finished downloading the preloaded tar for v1.18.0 on docker
cache.go:106] Downloading gcr.io/k8s-minikube/kicbase:v0.0.8@sha256:2f3380ebf1bb0c75b0b47160fd4e61b7b8fef0f1f32f9def108d3eada50a7a81 to local daemon
image.go:84] Writing gcr.io/k8s-minikube/kicbase:v0.0.8@sha256:2f3380ebf1bb0c75b0b47160fd4e61b7b8fef0f1f32f9def108d3eada50a7a81 to local daemon
profile.go:138] Saving config to /home/ri/.minikube/profiles/minikube/config.json ...
lock.go:35] WriteFile acquiring /home/ri/.minikube/profiles/minikube/config.json: {Name:mk3e177ff84a9b80716918e458a1d55c30d5128d Clock:{} Delay:500ms Timeout:1m0s Cancel:<nil>}

后面还有一处报错:

1
output: Unable to find image 'gcr.io/k8s-minikube/kicbase:v0.0.8@sha256:2f3380ebf1bb0c75b0b47160fd4e61b7b8fef0f1f32f9def108d3eada50a7a81' locally

这就很奇怪,因为我执行 docker images 是可以看到这个镜像的:gcr.io/k8s-minikube/kicbase:v0.0.8,起初我以为是镜像 pull 的不完整,找了台境外机器按照同样的流程执行了下,一切正常,pull 下来的镜像的 image id 和大小跟我本地是一样的

删除我本地的镜像,再次在我本地执行 minikube start 经过漫长等待后(我的代理慢)依旧是同样的报错,看来是 minikube 不认我本地这个镜像,难道是数据真的不完整?

阅读全文 »

原文:https://stackoverflow.com/a/17504505

中英对照:

  • Segment tree 线段树
  • Interval tree 区间树
  • Range tree 范围树
  • Binary indexed tree 二叉索引树

主要用于解决的问题:

  • Segment tree 存储区间,查询哪些区间包含给定的点
  • Interval tree 存储区间,查询哪些区间与给定区间相交,也支持点查询(Segment tree)
  • Range tree 存储点,查询哪些点落在了给定区间
  • Binary indexed tree 存储每个索引的项目数,查询索引 m 和 n 之间有多少个项目

性能(k 是结果数):

  • Segment tree O(n logn) 预处理时间,O(k+logn) 查询,O(n logn) 空间
  • Interval tree O(n logn) 预处理时间,O(k+logn) 查询,O(n) 空间
  • Range tree O(n logn) 预处理时间,O(k+logn) 查询,O(n) 空间
  • Binary indexed tree O(n logn) 预处理时间,O(logn) 查询,O(n) 空间

因工作需要,学习了原本十分抗拒的 perl 语言,不过整体看下来后发现 perl 也有其自身的特点与优势,看来每个语言都不可小觑。

由于时间比较急,所以在网上找了一篇速读文章学习,教程很棒,读完后对各种奇葩语法有了一定的认识,链接如下:

https://qntm.org/perl_cn

下面是一些小笔记:

获取数组长度,前面的 scalar 表示在 scalar 上下文中求 @array 的值,此时即为求数组长度

1
scalar @array

获取数组最大有效索引

1
$#array

引用(可以理解为指针)

1
2
@array = (1,2,3,4)
$array_ref = \@array

匿名结构(也是引用)

1
2
$array_ref = [1,2,3,4] # 与上一个 array_ref 一样,都是一个包含四个 scalar 的 array 的引用,但引用的对象不同
$hash_ref = {1 => 2, 3 => 4} # hash_ref 是一个包含两个键值对的 hash 的引用

引用取值

1
2
$array_ref -> [0] # 获取第一个 scalar 1
$hash_ref -> {1} # 获取 1 对应的值 2

解引用

1
2
@{ $array_ref } # 等价于 @$array_ref
%{ $hash_ref } # 等价于 %$hash_ref

阅读全文 »

使用 brew cask 安装的 macvim,版本为:8.1.2234,161

macvim 图形界面中文显示成问号,但在终端下面却可以正常显示,网上搜了很久都在说编码问题,其实不是,正解如下:

  1. 打开 macvim GUI
  2. 点击菜单栏-Preferences
  3. 点击 Advanced
  4. 取消选中 Use Core Text renderer 选项
  5. 重启 macvim GUI

最近在使用 clickhouse(下面简称 CH) 的 materialized view(下面简称为 MV)功能,类似其他数据库的物化视图,触发器之类的功能,不过遇到了几点坑,有的通过升级 CH 版本解决了,有的可以在写 sql 的时候小心避免。

先列一下我个人总结出来的使用要点,不想继续看的可以尝试依据这些要点看能否解决自己的问题:

  1. 在创建 MV 表时,一定要使用 TO 关键字为 MV 表指定存储位置
  2. 在创建 MV 表时如果用到了多表联查,不能为连接表指定别名,如果多个连接表中存在同名字段,在连接表的查询语句中使用 AS 将字段名区分开
  3. 在创建 MV 表时如果用到了多表联查,只有当第一个查询的表有数据插入时,这个 MV 才会被触发
  4. 在创建 MV 表时如果用到了子查询,且子查询会回查 SRC 表,那么这个子查询会回查整个 SRC 表,并不是只有新插入的那部分数据
  5. 在创建 MV 表时不要使用 POPULATE 关键字,而是在 MV 表建好之后将数据手动导入 MV 表

先看看官方的创建 MV 的语句:

1
CREATE MATERIALIZED VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT ...

具体的介绍可以阅读官方文档:https://clickhouse.yandex/docs/en/query_language/create/#create-view

值得一提的虽然官方提供了中文文档,但中文文档内容更新不及时,较英文文档有缺失的部分,还是建议阅读英文的。

我使用 MV 的场景是:

1
SRC -> MV1 -> MV2
阅读全文 »

zookeeper 崩溃恢复过程中两个关键性问题

Q1:leader 提交事务 A 后崩溃,follower 没有收到提交事务 A 的消息,再次选举 leader 时如何确保事务 A 被应用?

A1:既然 leader 已经在本地提交了事务 A,那么说明事务 A 肯定已经经过了多数 follower 的确认,即多数 follower 上都有事务 A 的记录,leader 崩溃后,重新选举出的新 leader 肯定包含未提交的事务 A,因为事务 A 的事务 ID 最大,新 leader 会继续提交事务 A。


Q2:leader 在还未将事务 B 广播到集群中时崩溃,在重新选举 leader 并在旧 leader 恢复正常后如何处理事务 B?

A2:事务 B 将会被删除,不会被提交。leader 在接收到一个请求,并将其转化为事务 B 后崩溃,此时还没有将事务 B 广播到集群中,即此事务只存在于 leader 机器上,经过新一轮的 leader 选举后,旧 leader 恢复正常并加入集群,此时会发现事务 B 的事务 ID 所使用的 epoch 号与新 leader 的对不上,那么事务 B 就会被删除。

应用场景

把握好 zookeeper 的主要特性就可以将其应用在多种多样的场景下。主要特性如下:

  • 节点
    • 树结构
    • 持久节点
    • 持久顺序节点
    • 临时节点
    • 临时顺序节点
    • 节点只能被注册一次
  • watcher

在《从 Paxos 到 Zookeeper》一书中提到的应用场景以及我认为场景所应用到的主要特性如下:

阅读全文 »