翻译自 clickhouse 官方入门教程第二节:https://clickhouse.yandex/tutorial.html

将 clickhouse 部署到集群

ClickHouse 集群是一个 homogenous 集群. 设置步骤是:

  1. 在集群内所有机器上安装 ClickHouse 服务端
  2. 在配置文件中设置集群相关的配置
  3. 在集群内每台机器上创建本地表
  4. 创建分布式表(Distributed table

在 ClickHouse 集群中分布式表事实上是一种关联到每台机器本地表的 view。对分布式表执行查询将使用集群中所有分片(译者注:一个分片即为集群中的一台机器)的资源。可以为多个集群指定配置,并创建多个分布式表以提供对不同集群的 view

下面的配置是一个有三个分片的集群,每个分片将数据保存到一个副本中(译者注:数据只有一份,没有副本):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<remote_servers>
<perftest_3shards_1replicas>
<shard>
<replica>
<host>example-perftest01j.yandex.ru</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>example-perftest02j.yandex.ru</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<host>example-perftest03j.yandex.ru</host>
<port>9000</port>
</replica>
</shard>
</perftest_3shards_1replicas>
</remote_servers>

创建本地表(译者注:待确定是否在所有分片上都创建本地表):

1
CREATE TABLE ontime_local (...) ENGINE = MergeTree(FlightDate, (Year, FlightDate), 8192);

创建分布式表,提供集群中本地表的 view:

1
2
CREATE TABLE ontime_all AS ontime_local
ENGINE = Distributed(perftest_3shards_1replicas, default, ontime_local, rand());

可以在集群的每个机器上都创建间一个分布式表。这将允许在集群中的任何一个机器上都能执行分布式查询。除了分布式表还可以使用 remote 表函数。

接下来在分布式表上执行 INSERT SELECT,以将该表扩展到多个服务器。

1
INSERT INTO ontime_all SELECT * FROM ontime;

阅读全文 »

目前 vscode 的 vim 插件支持在不同输入模式下自动切换输入法,可是 vscode 的配置目前不支持判断操作系统, 所以关于输入法切换的相关配置不能在 mac osx 和 linux 下通用,但是又不想因为这个问题维护两份 vscode 的配置文件,所以就想办法在 linux 使用 shell 脚本模仿了一个 im-select 的命令。

关于 vscode vim 插件输入法相关的配置可以到下面的链接中查看:

https://github.com/VSCodeVim/Vim#input-method

按照上面的链接在 mac osx 下安装 im-select 并在 vscode 中进行如下配置:

1
2
3
4
"vim.autoSwitchInputMethod.enable": true,
"vim.autoSwitchInputMethod.defaultIM": "com.apple.keylayout.ABC",
"vim.autoSwitchInputMethod.obtainIMCmd": "/usr/local/bin/im-select",
"vim.autoSwitchInputMethod.switchIMCmd": "/usr/local/bin/im-select {im}"

关于 vim.autoSwitchInputMethod.defaultIM,我在 mac osx 下用的英文输入法是 com.apple.keylayout.ABC,也可能是其他选项如:com.apple.keylayout.US,这个要根据具体情况来设置。

需要注意的是这个选项的值关系到下面脚本的内容,需要保持一致。

上面的配置在 linux 下会报错,因为上面在 mac osx 下安装的 im-select 没有提供对 linux 的支持,im-select 项目里建议直接使用 fcitx-remote 命令,链接如下:

https://github.com/daipeihust/im-select#fcitx

鉴于不想维护两份 vscode 配置文件的原因,分析了一下 vscode 调用 im-select 的情况,在 linux 使用 shell 实现了一个仿冒 mac osx 下 im-select 的脚本,脚本内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env bash

# this script in order to fake the im-select in mac osx for fcitx in linux

IM_EN="com.apple.keylayout.ABC"
IM_CN="2"

FCITX_CMD=/usr/bin/fcitx-remote

# there is no arguments that means query the current im
if [[ -z $@ ]]; then
if [[ "1" == $($FCITX_CMD) ]]; then
echo "$IM_EN"
else
echo "$IM_CN"
fi
else
if [[ "$@" == "$IM_EN" ]]; then
$FCITX_CMD -c
elif [[ "$@" == "$IM_CN" ]]; then
$FCITX_CMD -o
fi
fi

注意根据实际情况修正脚本中 IM_EN 变量的值,将脚本内容复制并保存到 /usr/local/bin/im-select 文件中即可,记得给文件增加可执行权限。

阅读全文 »

在 c/cpp 中可以使用 typedef 来给一个类型搞个别名:

1
2
3
4
5
typedef int myint;

// 下面 a 和 b 的类型都可以说是 int
int a;
myint b;

而函数别名的语法有些不同:

1
2
3
4
5
6
7
8
int max(int, int);
typedef int (* max_func_t)(int, int);

max_func_t max_alias;

// 下面的两个调用是等价的
max(1, 2);
max_alias(1, 2);

将函数指针作为参数时,使用函数别名可以大大提高代码的可读性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int max(int, int);

// 不使用别名,接收一个函数指针并调用
void test(int (* max_func)(int, int)) {
max_func(1, 2);
}
test(max);

typedef int (* max_func_t)(int, int);

// 使用别名,接收一个函数指针并调用
void test(max_func_t max_func) {
max_func(1, 2);
}
test(max);

函数别名的语法一直让我很奇怪写着也很难受,今天又碰到要将函数作为参数传递的情况,于是谷歌了一下,其实可以这样理解:

1
2
3
4
5
6
7
// 正确语法
typedef int (*max_func_t)(int, int);
// ^ ^ ^
// 返回类型 别名 参数

// 错误语法,但有助于理解(强行理解)
typedef int (*) (int, int) max_func_t;

以前只知道素数的定义:质数又称素数。一个大于 1 的自然数,除了 1 和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数。今天在学习《编程之法》(github) 时,第一章第二节 “字符串包含”,其提到的一种算法用到了素数,在此仅摘取原文部分内容作为记录。需要注意的是,这种算法并不是这个问题的最优解,具体请查看原文。

以下为原文摘录:


字符串包含

题目描述:
给定两个分别由字母组成的字符串 A 和字符串 B,字符串 B 的长度比字符串 A 短。请问,如何最快地判断字符串 B 中所有字母是否都在字符串 A 里?

为了简单起见,我们规定输入的字符串只包含大写英文字母,请实现函数 bool StringContains(string &A, string &B)

比如,如果是下面两个字符串:

String 1:ABCD

String 2:BAD

答案是 true,即 String2 里的字母在 String1 里也都有,或者说 String2 是 String1 的真子集。

阅读全文 »

翻译自:https://www.tonymacx86.com/threads/guide-how-to-patch-dsdt-for-working-battery-status.116102/

转载请注明出处

背景

因为电脑中的电池硬件与苹果的 SMbus 硬件不兼容,所以在笔记本电脑上运行 OS X 时,我们使用 ACPI 来访问电池状态。一般来说,我建议你使用 ACPIBatteryManager.kext,可在这里找到: https://github.com/RehabMan/OS-X-ACPI-Battery-Driver

AppleACPIPlatform 的更高版本无法正确访问 EC(嵌入式控制器)中的字段。由于各种 ACPI 方法(_BIF,_STA,_BST等)失效,这会导致 ACPIBatteryManager 获取电池数据出现问题。尽管可以使用较旧版本的 AppleACPIPlatform(来自 Snow Leopard),但还是希望使用最新版本的AppleACPIPlatform,因为对于具有 Ivy Bridge CPU 的计算机,它可以为这些计算机启用本机电源管理。要使用最新版本,必须更改 DSDT 以符合 Apple 的 AppleACPIPlatform 的限制。

特别是,EC 中大于 8 位的任何字段都必须更改为 8 位。 这包括 16、32、64 甚至更大的字段。

你应该先熟悉 DSDT/SSDT 打补丁的基本知识: http://www.tonymacx86.com/yosemite-laptop-support/152573-guide-patching-laptop-dsdt-ssdts.html

已存在的补丁

首先,你的笔记本电脑可能已经有补丁了。请看我的补丁仓库: https://github.com/RehabMan/Laptop-DSDT-Patch

为了使 DSDT 与补丁程序匹配,通常首先需要了解补丁程序的制作方式,以便你知道在 DSDT 中要查找的内容,并且可以将所看到的内容与现有补丁程序进行匹配。补丁集的更改比率很高,不会产生错误,并且似乎在补丁所有需要补丁的字段,这很可能是匹配的(本句原文:A patch set that has a high ratio of changes to patches, creates no errors, and appears to patch all fields that need to be patched is likely a match)。

阅读全文 »

记录一些在 windows 下将数据从 mysql 导入到 excel 过程中遇到的坑。首先,这一操作有两种方案:

  1. 在 navicat 中进行操作,将数据写入到 excel 文件中
  2. 在 excel 中进行操作,将数据从 mysql 服务器写入文件

第一种方案同事说在数据量很大的时候导出速度很慢,原因不明,我猜测是因为 navicat 使用的 POI 技术实现的功能,没有深究。第二种方案就我进行测试的方案,这种方案至少在速度方面有很明显的提升,下面列一下测试过程中遇到的坑:

  1. 只能使用 windows 的 office excel,wps 的表格有奇怪的问题无法解决(后来发现是因为系统中没有安装 Visual C++ Redistributable Packages for Visual Studio 2013
  2. 安装 Mysql ODBC 驱动时要注意 excel 的软件位数,如果 excel 是 32 位的,那么 Mysql ODBC 驱动也必须是 32 位的
  3. 64 位系统不显示 32 位的 ODBC 驱动,需要手动打开 C:\\Windows\\sysWOW64\\odbcad32.exe 程序添加连接
  4. 导入数据时出现错误:MySQL client ran out of memory,调整系统中的数据源(ODBC)中的连接选项,找到并勾选”Do not cache result”之类的选项,应该可以解决

转自:http://www.jctrans.com/tool/gjym.htm

国际域名缩写

国际域名缩写 国家或地区 Countries and Regions
AD 安道尔共和国 Andorra
AE 阿拉伯联合酋长国 United Arab Emirates
AF 阿富汗 Afghanistan
AG 安提瓜和巴布达 Antigua and Barbuda
AI 安圭拉岛 Anguilla
AL 阿尔巴尼亚 Albania
AM 亚美尼亚 Armenia
AO 安哥拉 Angola
AR 阿根廷 Argentina
AT 奥地利 Austria
AU 澳大利亚 Australia
AZ 阿塞拜疆 Azerbaijan
BB 巴巴多斯 Barbados
BD 孟加拉国 Bangladesh
BE 比利时 Belgium
BF 布基纳法索 Burkina-faso
BG 保加利亚 Bulgaria
BH 巴林 Bahrain
BI 布隆迪 Burundi
BJ 贝宁 Benin
BL 巴勒斯坦 Palestine
BM 百慕大群岛 Bermuda Is.
BN 文莱 Brunei
BO 玻利维亚 Bolivia
BR 巴西 Brazil
BS 巴哈马 Bahamas
BW 博茨瓦纳 Botswana
BY 白俄罗斯 Belarus
BZ 伯利兹 Belize
CA 加拿大 Canada
CF 中非共和国 Central African Republic
CG 刚果 Congo
CH 瑞士 Switzerland
CK 库克群岛 Cook Is.
CL 智利 Chile
CM 喀麦隆 Cameroon
CN 中国 China
CO 哥伦比亚 Colombia
CR 哥斯达黎加 Costa Rica
CS 捷克 Czech
CU 古巴 Cuba
CY 塞浦路斯 Cyprus
CZ 捷克 Czech Republic
DE 德国 Germany
DJ 吉布提 Djibouti
DK 丹麦 Denmark
DO 多米尼加共和国 Dominica Rep.
DZ 阿尔及利亚 Algeria
EC 厄瓜多尔 Ecuador
EE 爱沙尼亚 Estonia
EG 埃及 Egypt
ES 西班牙 Spain
ET 埃塞俄比亚 Ethiopia
FI 芬兰 Finland
FJ 斐济 Fiji
FR 法国 France
GA 加蓬 Gabon
GB 英国 United Kiongdom
GD 格林纳达 Grenada
GE 格鲁吉亚 Georgia
GF 法属圭亚那 French Guiana
GH 加纳 Ghana
GI 直布罗陀 Gibraltar
GM 冈比亚 Gambia
GN 几内亚 Guinea
GR 希腊 Greece
GT 危地马拉 Guatemala
GU 关岛 Guam
GY 圭亚那 Guyana
HK 香港特别行政区 Hongkong
HN 洪都拉斯 Honduras
HT 海地 Haiti
HU 匈牙利 Hungary
ID 印度尼西亚 Indonesia
IE 爱尔兰 Ireland
IL 以色列 Israel
IN 印度 India
IQ 伊拉克 Iraq
IR 伊朗 Iran
IS 冰岛 Iceland
IT 意大利 Italy
JM 牙买加 Jamaica
JO 约旦 Jordan
JP 日本 Japan
KE 肯尼亚 Kenya
KG 吉尔吉斯坦 Kyrgyzstan
KH 柬埔寨 Kampuchea (Cambodia )
KP 朝鲜 North Korea
KR 韩国 Korea
KT 科特迪瓦共和国 Republic of Ivory Coast
KW 科威特 Kuwait
KZ 哈萨克斯坦 Kazakstan
LA 老挝 Laos
LB 黎巴嫩 Lebanon
LC 圣卢西亚 St.Lucia
LI 列支敦士登 Liechtenstein
LK 斯里兰卡 Sri Lanka
LR 利比里亚 Liberia
LS 莱索托 Lesotho
LT 立陶宛 Lithuania
LU 卢森堡 Luxembourg
LV 拉脱维亚 Latvia
LY 利比亚 Libya
MA 摩洛哥 Morocco
MC 摩纳哥 Monaco
MD 摩尔多瓦 Moldova, Republic of
MG 马达加斯加 Madagascar
ML 马里 Mali
MM 缅甸 Burma
MN 蒙古 Mongolia
MO 澳门 Macao
MS 蒙特塞拉特岛 Montserrat Is
MT 马耳他 Malta
MU 毛里求斯 Mauritius
MV 马尔代夫 Maldives
MW 马拉维 Malawi
MX 墨西哥 Mexico
MY 马来西亚 Malaysia
MZ 莫桑比克 Mozambique
NA 纳米比亚 Namibia
NE 尼日尔 Niger
NG 尼日利亚 Nigeria
NI 尼加拉瓜 Nicaragua
NL 荷兰 Netherlands
NO 挪威 Norway
NP 尼泊尔 Nepal
NR 瑙鲁 Nauru
NZ 新西兰 New Zealand
OM 阿曼 Oman
PA 巴拿马 Panama
PE 秘鲁 Peru
PF 法属玻利尼西亚 French Polynesia
PG 巴布亚新几内亚 Papua New Cuinea
PH 菲律宾 Philippines
PK 巴基斯坦 Pakistan
PL 波兰 Poland
PR 波多黎各 Puerto Rico
PT 葡萄牙 Portugal
PY 巴拉圭 Paraguay
QA 卡塔尔 Qatar
RO 罗马尼亚 Romania
RU 俄罗斯 Russia
SA 沙特阿拉伯 Saudi Arabia
SB 所罗门群岛 Solomon Is
SC 塞舌尔 Seychelles
SD 苏丹 Sudan
SE 瑞典 Sweden
SG 新加坡 Singapore
SI 斯洛文尼亚 Slovenia
SK 斯洛伐克 Slovakia
SL 塞拉利昂 Sierra Leone
SM 圣马力诺 San Marino
SN 塞内加尔 Senegal
SO 索马里 Somali
SR 苏里南 Suriname
ST 圣多美和普林西比 Sao Tome and Principe
SV 萨尔瓦多 EI Salvador
SY 叙利亚 Syria
SZ 斯威士兰 Swaziland
TD 乍得 Chad
TG 多哥 Togo
TH 泰国 Thailand
TJ 塔吉克斯坦 Tajikstan
TM 土库曼斯坦 Turkmenistan
TN 突尼斯 Tunisia
TO 汤加 Tonga
TR 土耳其 Turkey
TT 特立尼达和多巴哥 Trinidad and Tobago
TW 台湾省 Taiwan
TZ 坦桑尼亚 Tanzania
UA 乌克兰 Ukraine
UG 乌干达 Uganda
US 美国 United States of America
UY 乌拉圭 Uruguay
UZ 乌兹别克斯坦 Uzbekistan
VC 圣文森特岛 Saint Vincent
VE 委内瑞拉 Venezuela
VN 越南 Vietnam
YE 也门 Yemen
YU 南斯拉夫 Yugoslavia
ZA 南非 South Africa
ZM 赞比亚 Zambia
ZR 扎伊尔 Zaire
ZW 津巴布韦 Zimbabwe

最近 coding 的 pages 服务越来越没法用了,不是自动部署失败就是博客无法访问,而且访问速度很慢,估计再过段时间 coding 就不再提供免费的 pages 服务了。但是如果将域名解析到 github 上,百度又无法抓取(github 不允许),思来想去还是放在自己的服务器上吧。

不过放在自己的服务器上有两个问题:

  • 没有备案不能使用 dnspod 的 301 重定向把 www 的域名重定向到顶级域名
  • 博客更新后不能自动部署

我的博客是个基于 hexo 的静态博客,可以使用 nginx 来提供 web 服务,同时 nginx 可以配置根据域名来重定向,这样就解决了第一个问题,博客内容就使用 git 仓库,注意这个仓库不是 markdown 的原始文件,而是经过 hexo 根据生成后的 html 站点,如果之前在 github 上部署过,在 github 上的仓库的名字应该会是 <UserName>.github.io 或者在 coding 上部署过那仓库名则是 coding 下跟用户名相同的仓库。以后更新了博客依然推送到 github 或者 coding 上,在自己的服务器上 clone 下仓库,然后使用 github 或者 coding 的 webhooks 功能更新自己服务器上的仓库,这样就解决了自己服务器上的博客不能自动部署更新的问题。

下面的例子是基于 github 的,coding 的操作类似,不过鉴于 coding 提供的服务不太稳定的问题,建议博客仓库托管也不要放在 coding 上了。

克隆博客仓库到服务器上

这一步很简单,跟克隆普通 git 仓库一样,我把仓库放在了 /opt/hexo-blog 下,如果不放在这个路径下,那后面的内容中的相应路径也要修改。

以我在 github 下的博客仓库为例,注意执行命令的用户权限,后面的命令都假设服务器上的账户是 root:

1
git clone git@github.com:listenerri/listenerri.github.io.git /opt/hexo-blog

这里使用了 ssh 协议的仓库地址,这需要将服务器的 ssh public key 部署在自己的 github 账户中,如果不想部署使用 https 协议的地址也可以,不过可能会需要输入用户名和密码,这会影响到后面 python 脚本中的功能,建议还是用 ssh 协议的地址,部署个 key 又不麻烦。

阅读全文 »

目前我遇到的两种需要指定 git 使用的 ssh 秘钥的场景是:

  • git 服务地址不同(一个公司,一个 github)
  • 同一个git 服务地址但账户不同

下面分开介绍。

服务地址不同

这估计是大多数人遇到的场景,同一个笔记本电脑,有时需要向公司的 git 服务推送代码,有时要向 github 推送代码,当然也可选择在两个不同的服务器上部署自己相同的公钥,但当无法做到这一情况时就要给 git 或者说给 ssh 命令指定哪个服务地址使用哪个秘钥。

首先生成两套秘钥即四个文件,两对公、私秘钥,具体的生成方法这里就不赘述了,不过要注意在生成第二套私钥时需要指定文件名称,否则将覆盖默认秘钥,一般秘钥文件存储在 ~/.ssh 目录下:

1
2
3
4
id_rsa
id_rsa.pub
id_rsa_company
id_rsa_company.pub

.pub 结尾的文件为公钥,需要将其部署在服务端,比如 id_rsa.pub 部署在 github 上,id_rsa_company.pub 部署在公司的服务上,id_rsa 则是 ssh 命令也是 git 命令使用的默认的私钥,当秘钥文件生成完成后使用以下命令将用于公司的私钥添加到 ssh-agent 中:

1
ssh-add ~/.ssh/id_ras_company

添加完成后可以查看已经添加过的私钥:

阅读全文 »

quilt 是一个管理补丁的工具,它使用了栈的概念来管理多个补丁,其管理的补丁一般被放在 patches 目录下,在这个目录下除了补丁文件还有一个 series 文件,这个文件中列出的补丁文件才是真正被打入项目的补丁文件,同时补丁文件在 series 文件中出现的顺序也是它们在栈中的顺序,没有包含在 series 文件中的补丁文件将不会被 quilt 管理,当新增或移除补丁时 quilt 会自动更新 series 文件不需要手动管理。

接触到这个命令是因为要给一个 deb 软件包打上我自己的补丁,但是 quilt 命令的 man 手册比较混乱,没有将相关的子命令放在一起进行介绍,下面将根据子命令之间的相关性总结下用到的和与之相关的子命令。

applied-unapplied

  • applied:列出包含在 series 文件中且已经应用(生效)了的补丁
  • unapplied:列出包含在 series 文件中但没有应用(生效)的补丁

diff

指定一个被打过补丁的项目文件并根据其变动生成一个 diff 文件,如果指定了补丁则只把指定补丁对项目文件的改动生成到 diff 文件,当同一个项目文件被多个补丁改动过,这个参数就有用了,如果不指定补丁则默认使用最顶层的补丁,如果被打过补丁的项目文件也没有指定,则将包含指定补丁或最顶层的补丁导致的所有项目文件变动。

files

列出最顶层的一个或指定的补丁改动了的所有项目文件

patches

列出所有改动了指定的项目文件的补丁

阅读全文 »