CodeWars 是一个面向工程的代码挑战网站。不同于 [[LeetCode]] 侧重于考察算法,CodeWars 更注重与工程代码,提供了基础的单元测试,以及不同语言的实现。
相较于 LeetCode CodeWars 上面的问题相对比较直接,有些甚至可以用来学习一些编程语言的特性。和 LeetCode 一样带有讨论版,可以通过讨论版来学习。
CodeWars 中也包含一些基础的算法,随着 Rank 越来越高也会有比较难的题目。
在注册进入 CodeWars 之后,会让用户选择不同的模式。
基础,升级,练习,Beta,随机。可以根据自己的需求选择。
如果看完上面的介绍你觉得 CodeWars 不错的话,可以点击 这里 来注册。如果你觉得又可以分享的解题思路,也可以点个 关注 一起来讨论。
eu.org 是欧盟组织下面的域名,EU 代表欧盟,Paul Mockapetris 在 1996 年的 9-10 月份创建了这个域名的 DNS 服务器。现在对个人和组织是免费注册的。
“EU.org, free domain names since 1996”。
eu.org 是 Google 认可的顶级域名。
优点:
缺点:
eu.org 在国内使用 http 会被被强行重置,配合 HTTPS 才可正常访问。
申请页面 https://nic.eu.org/arf/ 注册账号,验证邮箱。
点击 New Domain 申请域名。
在申请域名的时候需要提前填写 DNS 信息,但是 Cloudflare 不能提前添加未注册的域名,所以不能用 Cloudflare。
这里可以使用:
Hurricane Electric Hosted DNS(HE) NS Records:
DNSPOD 的 NS Record 一般都是 XXX.dnspod.com
之后 EU.org 会开始验证 NS 记录。如果没有问题最后的日志会是 done
。
---- Servers and domain names check
Getting IP for PHIL.NS.CLOUDFLARE.COM: 108.162.193.137 172.64.33.137 173.245.59.137
Getting IP for PHIL.NS.CLOUDFLARE.COM: 2803:f800:50::6ca2:c189 2606:4700:58::adf5:3b89 2a06:98c1:50::ac40:2189
Getting IP for VERA.NS.CLOUDFLARE.COM: 172.64.32.147 108.162.192.147 173.245.58.147
Getting IP for VERA.NS.CLOUDFLARE.COM: 2803:f800:50::6ca2:c093 2a06:98c1:50::ac40:2093 2606:4700:50::adf5:3a93
No error, storing for validation...
Saved as request 202303xxxxxxxx-arf-3xxxx
Done
这个过程的时间不确定,可能会是 1 天,也可能好几个星期,最后注册邮箱中会收到 EU.org 发过来的邮件,标题一般是 request [20210906172103-arf-xxxx] (domain test.EU.ORG) accepted
,这表示域名注册成功了。
Eu.org 在验证 NS 的过程中可能会出现如下错误:
SOA from NS1.HE.NET at 216.218.130.2: Error: Answer not authoritative (148.835 ms)
这个时候注意在前面选项 Name Servers 中选择 server names 单选项。
当 eu.org 域名申请完毕,可以将域名添加到 Cloudflare 管理。
首先需要在 eu.org 管理后台中修改域名的 nameservers 修改成 Cloudflare 的 NS 地址。
通常是:
这两个地址可以在 Cloudflare 后台添加域名之后获得。
在 Cloudflare 添加新申请的域名,如果添加的时候提示:
eu.org is not a registered domain
或者提示这个域名没有注册,就等待一下 EU.org 刷新 WHOIS,然后等待一会儿再尝试添加。
在看上一本 [[金融的本质]] 时突然对利率的变动比较好奇,所以就发现这一本《利率史》,一本关于利率变化历史的书籍。
在 [[金融的本质]] 一书中可以看到美联储可以通过影响隔夜拆借利率进而来影响整体市场的利率,从而通过利率来调控宏观经济。为什么利率对整个经济有如此巨大的影响?美联储加息成为了 2022 年全球经济的关键字。而国内房地产市场萧条,央行为什么通过调整房贷利率进而进一步影响房地产市场?这些问题都是我想通过这一本书想要了解的。
本书的作者是[[悉尼 霍默]],债券经纪人,职业早期创办了自己的债券公司,开了固定收益分析的先河。霍默率先应用了相对价值分析、收益曲线以及金融世界与经济的关系等分析工具。他是使用金融市场资金流动分析的第一人,远远早于美联储正式采用这种分析手段。1961 年来到所罗门兄弟公司,后组建并管理第一个严格局限于固定收益的研究部门。霍默首次提出将债券和其利息剥离,分别销售。
作者于 1983 年去世,本书的第四版由理查德·西勒修订,在第三版的基础上新增了 1990 年到 2005 年的世界。
就如书名所述,这是一本关于利率历史的书。作者通过对古代(史前史,美索不达米亚,希腊,罗马),中世纪,文艺复兴,以及近现代近 4000 年的经济史来叙述全世界各个地区的利率变化,进而去观察地区经济,以及民族兴盛和衰亡的历史。
公元前 1800 年,汉漠拉比法典就已经出现了对债务人和债权人相关的法律。 公元 600 年,希腊的索伦法典也对个人债务做出了规定,取消了利率的限制,豁免了过度的债务,以及取消个人劳役偿债。
公元前 450 年,罗马的《十二铜表法》也对信贷有所规定,贷款的利息被限制在每年不超过 8.333%,高于法定上限的利息将被处以 4 倍的赔偿。允许个人劳役偿债,但是得保证奴隶的健康。
公元 800 年《查理曼法典》,禁止一切贷款。
宗教改革之后,现代欧洲对收取利息合法化,利率成为了经济学家、金融家和政治家讨论的焦点,是放任自由还是国家控制。最终英国走了索伦的路子,废除了对利率的所有法律限制,而美国各州则在自己的高利贷法中确定了固定的利率上限,继承了汉谟拉比和古罗马的法律传统。
最高利率,伯林的 10000% ,最低纽约的 0.01% 。
20 世纪前 90 年,多事之秋,四大政治事件
三大经济事件:
这些事件对美国经济和利率产生了巨大影响。
利率是各国政府最直接影响的价格之一,历史的最终裁决会将近几十年利率幅震荡的一部分原因与政治因素联系在一起。
1917 年开始美联储采用欧洲已经使用很久的方式来影响利率,从而根本上改变了美国货币市场结构。通过集中银行储备金、设立最后贷款人机制,该立法终结了短期利率的无规律上涨(过去,只要出现急需贷款额超过资金供应量,就会出现短期暴涨)。短期利率仍然随着信贷供求关系的变化而起伏,但是有了封顶保底。建立美联储主要是希望通过短期商业借贷来提供一种灵活货币以服务于贸易。然而第一次世界大战不久就爆发,巨额的政府新债改变了货币市场,提升了美联储的政治责任。在接下来的几十年中,政府债务取代了银行和美联储银行投资组合中的商业票据的地位。新政、大萧条和第二次世界大战强化了这种趋势。并且利用低利率来促进就业,已经成为了一种政治目标。1921 年以前,美国的利率通常平均远远高于长期债券收益率,而在 1921 年之后,短期利率通常平均低于长期债券的收益率。
通胀在 1974 年达到两位数,OPEC 组织在 1973 年末实施石油价格急剧上涨措施,通胀蔓延到自由世界大部分地区。1974,1975 年的衰退降低里通胀率,但是 1979~1981 年通胀再次席卷而来,再次回到两位数,1979 年又一次石油价格飙升,物价飞涨,1980 年代的衰退对通胀几乎没有影响。利率上升到了美国历史上的最高水平,导致了 1981,1982 年的严重衰退,之后,通胀率在 80 年代后几年减弱到 3~5%。利率和收益率也随之下滑。
从 1946 年到 1981 年,美国经历了历史上最长的一个债券熊市,持续 35 年。
四件政治大事(一战、罗斯福新政、二战以及 1989 年前的冷战)和三大经济事件(建立美联储、经济大萧条以及 1965 年开始的大幅通胀)对于美国经济及美国利率产生了尤其重大的影响
1970 年以后的 20 年里,日本发展成为世界金融大国,从 20 世纪 50 年代开始到 70 年代,政府确定了几个重点发展对象,包括炼油、化工、工业机械和电子电器。高速发展阶段,日本采用豁免利息税的储蓄账户来鼓励个人大量存款。然而,日本的金融市场远不如西欧和北美发达,利率相对比较高;金融业比较分散,而不是集中的形式,利率受到管制,与其他国家的金融交易也受到控制。
70 年代中期,日本发生金融改革,浮动汇率,1973 年第一次石油危机,造成了管制型旧金融系统的紧张,经济已经发展到了规模巨大、在国际上非常重要的成都,无法在严格管制、封闭的金融系统下继续。日本在 1975 年放松了金融系统的大部分管制。日本货币市场和债券市场得以发展,伴随日本股市的发展,越来越向国外开放。尤其是 1975 年政府通过发行债券进行了大规模的融资以弥补财政赤字。
90 年代开始,日本的金融自由完善了许多,日本已经不再是一个高利率的国家。而事实上 80 年代,日本就成为了利率最低的国家之一。
在谈论所有其他的概念之前,我们先来回答一个问题,什么是利率?
利率的英文叫做 interest rate, 是利息率的简称。在 Longman 词典中的解释是:
the percentage amount charged by a bank etc when you borrow money, or paid to you by a bank when you keep money in an account there
新闻中常常提到美联储加息或降息,很多人都会误认为美联储可以直接决定利率,而事实是美联储只能通过控制货币供给量来决定短期利率。但是影响经济最重要的是实际利率或者称为通胀调整利率(市场利率减去通胀率)。实际利率才是对资本决策最有实质性影响的。美联储影响长期实际利率的能力是间接的。实际利率受到经济因素影响,包括经济前景这些是不受美联储控制的。
作者试图通过漫漫历史长河的利率变化来给读者展示国家和文明的兴衰,作者认为在一个自由市场条件下,长期利率的趋势可以帮助分析这个国家的经济和政治状况。
几乎在所有的教科书或百科上面都会提到,几乎所有的国家都会将利率作为调节宏观经济的重要工具,当经济过热,通胀上升的时候就提高利率,收紧信贷。当通胀得到控制,便把利率适当的调低。
就如作者所说,本书的目的并不是为了探讨利率波动对于社会和经济方面带来的后果,而只是要搜寻、记录并分析多个国家数世纪中通行利率。
在我个人看来本书的一大优点同样也是其最大的缺点,就是数据太翔实,大面积的原始数据,以至于欠缺了作者更深入的思考和总结。并且这些数据大大影响了阅读体验,不过如果是作为一本参考书来说,倒是非常不错的资料。
Elasticsearch 既然作为一个全文检索引擎,那么自然需要将数据导入,让 Elasticsearch 去索引。
Elasticsearch(后简写为 ES) 的基本单元是文档,使用 JSON 来描述。
有很多方法可以把数据导入到 ES:
导入数据前要了解的知识。
如果数据文件比较简单,只有单层 JSON 结构,并且小于 1MB,可以使用 POST 请求直接将数据提交到 ES。
假设有数据 accounts.json
:
{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
然后可以使用如下命令导入:
curl -u admin:my_elastic_pass -H 'Content-Type: application/json' -XPOST 'http://localhost:9200/accounts/_doc/_bulk?pretty' --data-binary @accounts.json
返回:
{
"_index" : "accounts",
"_id" : "_bulk",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 0,
"_primary_term" : 1
}
可以通过如下命令来查看所有索引的情况:
curl "localhost:9200/_cat/indices?v"
然后访问 Kibana,在后台就可以查询导入的内容:
这里使用官方的样例数据:
wget https://download.elastic.co/demos/kibana/gettingstarted/accounts.zip
unzip accounts.zip
curl -XPOST 'localhost:9200/bank/account/_bulk?pretty' --data-binary @accounts.json
需要注意的是如果使用 Bulk 批量导入,那么格式需要按照:
action_and_meta_data\n
optional_source\n
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n
或者可以在 Kibana 后台,点击侧边栏 Dev Tools,然后在编辑框中输入:
POST bank/_bulk
{"index":{"_id":"1"}}
{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
{"index":{"_id":"6"}}
{"account_number":6,"balance":5686,"firstname":"Hattie","lastname":"Bond","age":36,"gender":"M","address":"671 Bristol Street","employer":"Netagy","email":"hattiebond@netagy.com","city":"Dante","state":"TN"}
省略...
最后点击执行。
执行成功后,可以运行 curl localhost:9200/bank/_search
,如果返回值中 value
是导入的条数就表示成功了。
Logstash 是开源的服务器端数据处理管道,能够同时从多个来源采集数据、转换数据,然后将数据发送到 Elasticsearch 中。Logstash 的官方文档请参见:https://www.elastic.co/guide/en/logstash/current/getting-started-with-logstash.html
[[Elasticsearch]] 是基于 [[Lucene]] 开源的全文搜索引擎。提供 RESTful 接口,可以实现精确快速的实时检索。
[[Kibana]] 是一个基于 Web 的可视化前端。还有一个 [[elasticsearch-head]] 也是一个 Elasticsearch 的前端,不过这里因为 Kibana 使用场景更加广泛,就选择 Kibana。
创建 network:
docker network create elastic
这里仅演示单节点的 Elasticsearch 搭建过程,如果要搭建集群模式,可以自行参考官网。
version: "3.0"
services:
elasticsearch:
container_name: es
image: elasticsearch:8.3.2
environment:
- xpack.security.enabled=false
- "discovery.type=single-node"
- "ELASTIC_PASSWORD=${ELASTIC_PASSWORD}"
networks:
- elastic
ports:
- 9200:9200
kibana:
container_name: kibana
image: kibana:8.3.2
environment:
- ELASTICSEARCH_HOSTS=http://es:9200
networks:
- elastic
depends_on:
- elasticsearch
ports:
- 5601:5601
networks:
elastic:
driver: bridge
Docker compose 会启动两个容器,一个容器运行 Elasticsearch,使用端口 9200,一个容器运行 Kibana 使用端口 5601.
两个镜像最新的版本可以分别在这里查看:
使用如下的命令检查 Elasticsearch 的状态:
❯ curl http://localhost:9200
{
"name" : "d9f0b969f13c",
"cluster_name" : "docker-cluster",
"cluster_uuid" : "VRWzzZpISPugOCQadlC88A",
"version" : {
"number" : "8.3.2",
"build_type" : "docker",
"build_hash" : "8b0b1f23fbebecc3c88e4464319dea8989f374fd",
"build_date" : "2022-07-06T15:15:15.901688194Z",
"build_snapshot" : false,
"lucene_version" : "9.2.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
当启动 Elasticsearch 之后会产生一些证书,这些证书用来安全的在 Kibana 中访问 Elasticsearch。
http_ca.crt
:CA 证书,用来签名 HTTP 请求http.p12
:Keystore that contains the key and certificate for the HTTP layer for this node.transport.p12
:Keystore that contains the key and certificate for the transport layer for all the nodes in your cluster.http.p12
和 transport.p12
是密码保护的 PKSC#12 keystore。
可以使用如下命令获取 http.p12
密码:
bin/elasticsearch-keystore show xpack.security.http.ssl.keystore.secure_password
可以使用如下命令获取 transport.p12
密码:
bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password
等待容器启动之后可以直接访问 Kibana http://localhost:5601/
FFmpeg 可以使用 -i
参数来输入一个或多个文件,但有些时候会有一些将多个文件串联成一个文件的需求。比如将多个视频合并成一个视频文件,将多个音频文件合并和一个长音频文件。这个时候就需要使用到 FFmpeg 的 concat demuxer
。
concat demuxer
是 FFmpeg 1.1 引入的。主要可以用来合并多个媒体文件。
FFmpeg 有两种方式可以串联相同的文件:
demuxer
更加灵活,需要相同的编码,容器格式可以不一样。而 protocol
则需要容器的格式也一致。
demuxer
通过从一个固定格式的文件中读取文件列表,然后 FFmpeg 可以对这些文件一同处理。
创建文件 mylist.txt
,包含所有想要串联的文件:
# this is a comment
file '/path/to/file1.wav'
file '/path/to/file2.wav'
file '/path/to/file3.wav'
注意,这里的 #
是注释语句。文件中的文件路径可以是绝对的或相对的路径,然后就可以使用 FFmpeg 对这多个文件 stream-copy 或者 re-encode(重新编码) :
ffmpeg -f concat -safe 0 -i mylist.txt -c copy output.wav
如果路径是相对的,这里的 -safe 0
可以省略。
如果有多个文件要添加到 mylist.txt
文件中,可以使用 Bash 脚本批量生成:
# with a bash for loop
for f in *.wav; do echo "file '$f'" >> mylist.txt; done
# or with printf
printf "file '%s'\n" *.wav > mylist.txt
demuxer
在文件流级别工作,concat protocol
在文件级别工作。特定的文件(比如 MPEG-2 传输流,或者其他)可以串联起来。
下面的命令将三个 MPEG-2 TS 文件串联到一起,不重编码:
ffmpeg -i "concat:input1.ts|input2.ts|input3.ts" -c copy output.ts
某些情况下,多个文件可能使用不同的编码,那么上面的命令就都无法使用。
如果要让 concat filter 工作,输入的文件必须拥有相同的 frame dimensions (eg. 1920*1080 pixels) 并且要有相同的 framerate。
假设有三个文件需要串联起来,每一个文件都有一个视频流和一个音频流:
ffmpeg -i input1.mp4 -i input2.webm -i input3.mov \
-filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]concat=n=3:v=1:a=1[outv][outa]" \
-map "[outv]" -map "[outa]" output.mkv
来拆解一下命令,首先指定所有的输入文件,然后实例化一个 -filter_complex
filtergraph
然后:
[0:v:0][0:a:0][1:v:0][1:a:0][2:v:0][2:a:0]
告诉 ffmpeg 使用输入文件中的哪一个流,然后发送给 concat filter。在这个例子中,第一个文件的视频流 0 [0: v:0]
和音频流 0 [0: a:0]
,第二个文件的视频流 0 [1: v:0]
和音频流 0 [1: a:0]
。
concat=n=3:v=1:a=1[outv][outa]
这个就是 concat fitler, n=3
告诉 filter 这里有三个输入分段,v=1
则表明每一个分段有一个视频流,a=1
表明每一个分段有一个音频流。filter 然后将这些分段连接产生两个输出流, [outv]
和 [outa]
两个输出流的名字。
注意的是两侧的双引号是必须的。
然后使用这些输出流,将他们 组合成输出文件 :
-map "[outv]" -map "[outa]" output.mkv
这行告诉 FFmpeg 使用 concat filter 的结果,而不是直接使用输入的 streams。
有一个叫做 mmcat 的 Bash script,可以在老版本的 FFmpeg 中实现 concat filter。
Hestia CP 是一个开源的 Linux 服务器控制面板(Control Panel),HestiaCP fork 自另一款流行的控制面板 VestaCP 。由于 VestaCP 开发和维护趋于停止,很多安全问题和漏洞没有及时修复,所以有人从 VestaCP 拉出新分支进行开发和维护。Hestia 可以作为 aaPanel(宝塔面板)的很好的开源代替。
HestiaCP 提供了一个简单干净的网页界面,给网站维护人员提供了更加简单的方式维护网页服务器。HestiaCP 提供了很多功能,包括
HestiaCP 还提供了基于命令行的管理工具,具体可以见 文档。
另一个值得一说的功能就是,HestiaCP 提供了一键安装网站(Quick Install App)的功能,默认提供了一些非常受欢迎的网页应用,包括 [[WordPress]], [[Drupal]], [[Joomla]], [[Opencart]], [[PrestaShop]], [[Lavarvel]], [[Symfony]] 等等。
在接触 Hestia 之前,有段时间直接使用 LNMP,或者使用 [[aapanel]],但后来发现 aaPanel 的 License 或许存在某些问题,并且在读了 Stallman 的 著作 之后对自由软件的认识更深刻了一些,所以直接替换成 GPL 发布的 Hestia。作为 aaPanel 的开源代替品,发现 Hestia 还是非常不错的。
后台演示:
sudo
本文中演示在 Ubuntu 20.04 上安装 HestiaCP。整个过程可能会需要 15 分钟左右。
安装脚本:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
bash hst-install.sh
可以通过 安装器 自己选择安装的组件。选择组件之后会产生一个命令:
wget https://raw.githubusercontent.com/hestiacp/hestiacp/release/install/hst-install.sh
sudo bash hst-install.sh --apache no --phpfpm yes --multiphp no --vsftpd yes --proftpd no --named yes --mysql yes --postgresql no --exim yes --dovecot yes --sieve no --clamav no --spamassassin no --iptables yes --fail2ban yes --quota no --api yes --interactive yes --with-debs no --port '8083' --hostname 'your_hostname' --email 'i@youremail.com' --password 'your_password' --lang 'en'
你可以根据自己的需要自行选择需要的组件。可以在官网 文档 中查看默认会安装的组件。
安装完成之后会在日志中看到后台登录的链接,以及默认的用户名(admin)和密码。脚本执行完成后可能会需要一次重启来完成安装。
访问 https://ip:8083
,或者如果已经配置了域名 A 记录指向该 IP,也可以使用域名加端口来访问。
安装过程中如果遇到:
[ * ] Installing dependencies...
!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
WARNING: Your network configuration may not be set up correctly.
Details: The netplan configuration directory is empty.
You may have a network configuration file that was created using systemd-networkd.
It is strongly recommended to migrate to netplan, which is now the
default network configuration system in newer releases of Ubuntu.
While you can leave your configuration as-is, please note that you
will not be able to use additional IPs properly.
If you wish to continue and force the installation,
run this script with -f option:
Example: bash hst-install-ubuntu.sh --force
!!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!! !!!
Error: Unable to detect netplan configuration.
这个错误是因为 Ubuntu 没有使用 netplan,或者 VPS 主机提供的镜像没有使用 netplan,但是 /etc/netplan
文件夹存在,这就导致 HestiaCP 安装脚本执行过程中判断错误。
解决方案:查看 /etc/netplan
文件夹,如果配置文件夹是空的,那么可以直接删除该文件夹,如果确定自己已经使用了 netplan 作为网络配置,那么检查一下网络配置。
在完成安装访问后台的时候,浏览器会报 Your connection is not private 的错误,这是因为 SSL 证书缺失了。
可以使用 v-add-letsencrypt-host
命令来申请证书。
不过我在执行的过程中发生一些问题,报错:
Error: Let's Encrypt validation status 400 (xxx.einverne.info). Details: Unable to update challenge :: authorization must be pending
Error: Let's Encrypt SSL creation failed
查看发现因为在机器上安装了 Docker,所以虚拟了一个网络端口,在后台 Web 查看域名的时候,看到其中关联的 IP 地址是一个本地的地址 172.17.0.1
,把这个地址修改成 VPS 的真实 IP 地址。然后重新执行命令即可。
如果出现其他的错误,也可以到如下的目录中查看日志:
/var/log/hestia/LE-user-domain-timestamp
虽然以 admin
登录可以在后台做任何事情,但是还是推荐创建一个新用户,以新用户的身份来操作。
创建完用户之后以该用户登录,然后在 Web 中,选择添加域名。
添加的过程中有如下配置:
在高级选项中:
www.yourdomain.com
指向你的域名AWStats
,可以到其 官网 查看/home/your_user/web/your_website/public_html/
可以在 /usr/local/hestia/data/templates/web/nginx/
目录下查看到默认的 Nginx 配置模板。其中的默认模板:
default.tpl
default.stpl
可以将默认的模板拷贝到新的文件修改:
cp original.tpl new.tpl
cp original.stpl new.stpl
cp original.sh new.sh
模板中支持的变量可以参考官网
默认情况下 HestiaCP 使用 8083 端口,当然在安装的时候也可以指定,但是如果安装完成之后想要调整端口,可以使用如下的命令:
v-change-sys-port 2083
更改 admin 用户密码
v-change-user-password admin yourpass
或者更改其他任何用户的密码。
v-change-sys-hostname your.hostname
强制主机名使用 SSL
v-add-letsencrypt-host
v-add-web-domain-ssl-hsts 'admin' 'hcp.domain.com'
v.add-web-domain-ssl-force 'admin' 'hcp.domain.com'
rm -fr /usr/local/hestia/install/rhel
rm -fr /usr/local/hestia/install/ubuntu
rm -fr /usr/local/hestia/install/debian/7
rm -fr /usr/local/hestia/install/debian/8
rm -fr /usr/local/hestia/install/debian/9
touch /etc/iptables.up.rules
v-add-firewall-rule ACCEPT 0.0.0.0/0 22 TCP SSH
v-add-firewall-rule ACCEPT 0.0.0.0/0 5566 TCP HestiaCP
source /etc/profile
PATH=$PATH:/usr/local/hestia/bin && export PATH
可以使用命令行:
v-update-sys-ip 1.2.3.4
v-rebuild-web-domains admin
v-rebuild-mail-domains admin
HestiaCP 是 VestaCP fork,VestaCP 开发和维护趋于停止,存在许多漏洞和安全性问题。VestaCP 是第一个 Nginx 的 GUI 控制面板。在 VestaCP 之前有很多 CLI-only 的管理工具。
[[Elasticsearch]] 是一款基于 [[Lucene]] 的开源的、分布式的搜索引擎。提供一个分布式、多租户的全文搜索引擎。提供 HTTP Web 界面和 JSON 格式接口。
Elasticsearch 由 Java 实现,是目前最流行的大数据存储、搜索和分析引擎。
GitHub:https://github.com/elastic/elasticsearch
大数据要解决三个问题:
但 Elasticsearch + Kibana 的组合可以快速解决如上提到的问题。
Elasticsearch 是面向文档的,存储整个文档或对象,内部使用 JSON 作为文档序列化格式。
在使用 Linux 安装之前设置 vm.max_map_count
至少是 262144.
使之生效:
sudo sysctl -w vm.max_map_count=262144
让系统重启之后也生效,需要编辑 /etc/sysctl.conf
添加一行:
vm.max_map_count=262144
通过 docker-compose 安装。
也可以下载手动安装。
我个人推荐在本地使用单节点安装启用。
默认情况,Elasticsearch 通过 9200 端口对外提供 REST API。Kibana 的默认端口是 5601。
如果遇到如下问题,请查看是否设置了 vm.max_map_count
。
es03_1 ERROR: [1] bootstrap checks failed. You must address the points described in the following [1] lines before starting Elasticsearch.
单节点的 Elasticsearch 可以使用 Docker 在本地启用,参考这里。
常用命令:
docker network create elastic
docker run --name es --net elastic -p 9200:9200 -p 9300:9300 -it docker.elastic.co/elasticsearch/elasticsearch:8.3.1
docker exec -it es /usr/share/elasticsearch/bin/elasticsearch-reset-password
Node,节点,Elasticsearch 运行实例,集群由多个节点组成。节点存储数据,并参与集群索引、搜索和分析。
Shard, 分片,数据中的一小部分,每一个分片是一个独立的 Lucene 实例,自身也是一个完整的搜索引擎。
索引会存储大量的数据,这些数据会超出单个节点的硬件限制,例如,占用 1TB 磁盘空间的 10 亿个文档的单个索引可能超出单个节点的磁盘容量,所以 Elasticsearch 提供了索引水平切分(Shard 分片)能力。
创建索引时只需要定义所需分片数量。每一个分片本身就是一个具有完全功能的独立「索引」,可以分布在集群中的任何节点上。
文档会被存储并被索引在分片中。但是当我们使用程序与其通信时,不会直接与分片通信,而是通过索引。
当集群扩容或缩小时,Elasticsearch 会自动在节点之间迁移分配分片。
分片分为:
从分片是主分片的副本,提供数据的冗余副本,在硬件故障时提供数据保护,同时服务于搜索和检索只读请求。
索引中主分片的数量在索引创建之后就固定了,但是从分片数量可以随时改变。
设置三个主分片和一组从分片
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
分片很重要:
Index, 索引。在 Elasticsearch 中,存储数据的行为叫做索引 Indexing,在索引数据值前,要决定数据存储在哪里。
单个集群中可以定义任意多索引。
一个 Elasticsearch 集群可以包含多个索引(数据库),可以包含很多类型(表),类型中可以包含很多文档(行),文档中包含很多字段(列)。
关系数据库 -> 数据库 -> 表 -> 行 -> 列 (column)
Elasticsearch -> 索引 -> 类型 -> 文档 -> 字段(field)
在 Elasticsearch 中索引有不同的含义。
索引就是 Elasticsearch 提供的「数据库」。
为文档创建索引,就是将文档存储到索引(数据库)中的过程,只有建立了索引才能被检索。
在关系型数据库中为某一列添加索引,是在文件结构中使用 B-Tree 加速查询。在 Elasticsearch 和 Lucene 中使用 Inverted index (反向索引)的结构来实现相同的功能。
通常文档中的每一个字段都被创建了索引(有一个反向索引)
假如要创建员工名单:
PUT /corp/employee/1
{
"first_name" : "John",
"last_name" : "Smith",
"age" : 25,
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
employee
类型corp
索引中Document 文档,可被索引的基本信息单元。文档以 JSON 表示。单个索引理论上可以存储任意多的文档。
副本在分片或节点发生故障时提供高可用。
分片和对应的副本不可在同一个节点上
副本机制,可以提高搜索性能和水平扩展吞吐量,因为可以在所有副本上并行搜索。
默认情况下,Elasticsearch 中的每个索引都分配一个主分片和一个副本。集群至少需要有两个节点,索引将有一个主分片和一个完整副本。
Elasticsearch 提供了灵活的查询语言,可以完成更加复杂的搜索任务。
使用 JSON 作为主体:
GET /megacorp/employee/_search
{
"query" : {
"match" : {
"last_name" : "Smith"
}
}
}
Elasticsearch 有一项功能叫做 Aggregation,类似于 GROUP BY,但是更强大。结合查询语句可以实现非常多的聚合操作。
Elasticsearch 可以被扩展到上百成千台服务器来处理 PB 级别的数据。Elasticsearch 是分布式的。用户在使用的过程中不需要考虑到分片,集群等等,这些都是 Elasticsearch 自动完成的:
集群健康状态查询:
GET /_cluster/health
{
"cluster_name": "elasticsearch",
"status": "green", <1>
"timed_out": false,
"number_of_nodes": 1,
"number_of_data_nodes": 1,
"active_primary_shards": 0,
"active_shards": 0,
"relocating_shards": 0,
"initializing_shards": 0,
"unassigned_shards": 0
}
其中 status 有三个状态:
集群健康状况:
GET /_cat/health?v
列出节点信息:
GET /_cat/nodes?v
列出集群中索引信息:
GET /_cat/indices?v
创建索引:
PUT /customer?pretty
GET /_cat/indices?v
之前在 Twitter 上看到一则帖子,有人求推荐书,如果要向一位学金融的朋友推荐一本计算机入门书籍,你会选择哪一本?在答复里面,我看到了有人推荐这一本《编码:隐匿在计算机软硬件背后的语言》。所以我把这一本书作为 [[20220627 21 天挑战计划]] 中要阅读的一本书。当时我没有想到的是,在豆瓣标记的时候我意外发现我早已经在 2018 年标记读过,但当时没有做笔记,也没有整理标记,4 年过去,就像没有读过一样。这更加坚定了我之后读书一定要整理书摘,用自己的语言撰写一下读书笔记的决心。
编码是一本由实体世界中信息传递,进而一步步带领读者进入计算机编码的通俗读物。作者会使用通俗易懂的语言,循序渐进地引领读者理解计算机是如何工作的。
作者在本书的开头引用了《美国传统英语词典》对编码(code)的解释:
这其中可以看到两层含义,一种是表达在信息传输过程中用来表述字母或数字的信号,可以是直接的信号,也可以是加密的,或简练的信息;另外一层含义是由字符和规则组成的系统用来向计算机传达指令。
同样在《牛津高阶英汉词典》中的解释更为直接:
也就是,计算机编程指令系统。
而在本书中,编码特指的是在机器和人之间传递信息的方式。我们所编写的代码,需要让计算机可以理解执行。
我们都知道一个国际求救信号 SOS,但为什么是 SOS 呢,是什么的缩写吗?是比较好读吗?其实都不是,而原因是因为在莫尔斯编码中,S 是三个点,而 O 是三个划(-),SOS 是一个比较容易记忆的编码序列,并且不容易和其他序列搞混。于是这个编码就作为国际通用的求救信号留了下来。
莫尔斯编码通过对字母进行点和划的编码以实现信息的传递,但这个效率无疑是比较低的,如果在手动操作的情况下,每分钟也只能传递各位数字的单词,而通过口头交流可以达到每分钟 100 个单词左右的速度。
布莱叶盲文通过凸起的点编码文字,使得盲人可以阅读。布莱叶盲文通过三行两列的六个凸起的点编码信息,布莱叶盲文也是一种二进制编码方式,每一个凸起的点可以表示两种状态,通过不同的组合,六位的编码可以表达出 2^6,也就是 64 种不同的编码。
除了 24 个字母,为了使用的简便,后续人们还引入了字母组合,常用单词,充分利用这 64 种不同的变化。
作者在介绍了莫尔斯编码和布莱叶盲文之后用了整整一章的内容介绍了手电,以及基本的电路知识,也许你会感到奇怪为什么在这个时候介绍了这么多电流、电压、电阻、功率的知识。但电气化的开始才是之后计算机时代来临的前提。
欧姆定律:
I = E / R
电流(I)等于电压(电动势 E)除以电阻(R)。
瓦特:
P = E * I
瓦特等于电压(E)乘以电流(I)。
但作者真正要介绍的并不是这些物理知识,而是控制电灯的开关,这一个开关,又可以将一个最简单的电路(手电)变成一个二进制的编码,开和关分别是两个状态。
电报系统的诞生正式开启了全球即时通信的时代,但是电报是怎么来的呢?想想一想如果将一个简单的控制电灯开关的电路系统分别放到你和朋友的家中,那你们就可以分别通过开关来控制对方家中的电灯,那么就可以信息的传递。电路系统使用的原理就是如此:在线路的一端通过一些措施,使得线路的另一端发生某种变化。
[[萨缪尔 莫尔斯]] 通过电磁现象在 1836 年通过专利局,成功发明电报机,但直到 1843 年,才说服国会为其创建公共基金。1844 年 5 月 24 日,华盛顿特区和马里兰州巴尔迪摩市电报线路架设完成,完成了人类历史上第一条信息的传递:「What hath God wrought!」
电报机的发明标志着现代通信的开始,人们第一次能够在视线或听力之外的距离开始实时交流,信息的传递速度比骏马还有快。
但是电报机最大的问题是长导线带来的电阻,电报线路使用高达 300 伏的电压使得有效距离可以超过 300 英里,但线路还是无法无限延长。
于是人们发明了中继系统,每隔 200 英里设定一个中继,接收信息,然后再转发出去。于是人们发明了继电器。通过电路的方式将信息转发出去。
全球通用的数字系统通常被称为阿拉伯数字,起源于印度,被阿拉伯数学家带入欧洲。波斯数学家穆罕默德·伊本穆萨·奥瑞兹穆(根据这个人的名字衍生出英文单词 algorithm)在公元 825 年写了一本关于代数的书,使用了印度计数系统。
这个 0,是数字和数学史上最重要的一个发明。0 的出现简化了乘法和除法。
因为人类是有 10 个手指,所以适应了 10 进制,于是作者通过循序渐进的方式提问,如果是 4 指动物呢?于是进一步介绍了 8 进制,再如果是龙虾呢?两个大钳子,4 进制,再如果是海豚呢?两个鳍,2 进制。
当我们把数字系统减少到只有 0 和 1 的二进制系统时,我们无法找到比二进制系统更加简单的数字系统了。但是之前提到过的所有开关、电线、灯泡、继电器都可以用来表示二进制的 0 和 1。
1948 年,美国数学家约翰·威尔德·特克(John Wilder Turkey)意识到随着计算机的普及,二进制可能为发挥极大作用,所以发明了一个新的、更短的词语来替代不方便的 binary digital,选择了短小、简单、精巧的词 bit。
交换律:
A + B = B + A
A * B = B * A
结合律:
A + (B + C) = (A + B) + C
A*(B*C) = (A*B)*C
分配率:
A*(B+C) = A*B + A*C
传统代数是处理数字的,布尔的天才在于将代数从数的概念中抽离出来,更加抽象。在布尔代数中,操作数不是数字而是类(class),简单来说,一个类就是一个食物的群体(集合 Set)。
布尔代数中,符号 + 表示两个集合的并集,x 表示两个集合的交集。
但是布尔生活的那个时代,没有人把布尔代数用于电路。直到 20 世纪 30 年代的香农。
克洛德·艾尔伍德·香农在 1938 年,完成了《继电器和开关电路的符号分析》(A Symbolic Analysis of Relay and Switching Circuits)一篇著名的硕士论文,并在 10 年之后,发表《通信的数学原理》(The Mathematical Theory of Communication) 清晰尔严谨地阐述了,电子工程师可以运用布尔代数的所有工具去设计开关电路。如果简化了一个网络的布尔表达式,那么也可以简化相应的电路。
于是人们在简单的电路基础上抽象出了与门、或门、与非门、与或门等等。
8 比特表示一个字节(byte),8 比特在很多方面都比单独的比特更胜一筹。
全世界大部分书面语言(除了中日韩中使用的象形文字)的基本字符都少于 256 ,字节是一种理想的保存文本的手段。
当一个字节无法表示所有信息时,使用两个字节,也可以很好的表达。
20 世纪 40 年代初期,真空管开始取代继电器,到 1945 年,真空管已经完全取代了继电器。
晶体管不再需要真空而是使用固体制造,体积比真空管更小,晶体管需要的电量更小,产生的热量更小,更持久耐用。
开发真空管的最初目的是为了放大电信号,但是同样可以应用于逻辑门的开关,作用和晶体管一样。
诺伊斯在 1957 年与其他 7 位科学家离开肖克利半导体创办仙童(Fairchild)半导体公司,并随后发明了集成电路。
1965 年摩尔(Moore)发现从 1959 年开始,同一块芯片上可以集成的晶体管数目每年番一倍。
到 20 世纪 70 年代,使用集成电路在一块电路板上制造一个完整的计算机处理器变得可能。
在比较微处理器时使用三个标准:
到 1972 年 4 月,英特尔发布 8008 芯片,一个时钟频率位 200KHz,可寻址空间为 16 KB 的 8 位微处理器。
虽然看到介绍已经大致了解了这绝不是一本晦涩难懂的书,但还是惊讶于作者可以将电路,布尔代数等等复杂的概念如此深入浅出地描述给作者,并且中间穿插非常多的物理学、数学发展历史,以及历史上这种对计算机硬件发展起决定性作用的部件,继电器,晶体管等等,让这一本书不但在了解计算机组成部分之外还了解到了大量有趣的历史决定时刻,让我感受到了那个天才,英雄辈出的时代精神。
在读书的过程中,不断地有各个时期学过的课程浮现在眼前,物理中的电磁学,到大学时期的,电路,代数,汇编等课程,在阅读的过程中非常享受所有知识融为一体的感觉。
曾经有一个问题总是困扰着我,[[人类为什么在近 200 年发展如此快]]?在这一本书中我更进一步的体会到了如下的几点:
在作者对芯片的描述中,作者总结出三点去描述微处理器,时钟频率,可寻址字节数,以及位数,而这三者则是作者铺垫了非常多章节的内容,当我读到时顿时感受到了作者清晰的写作思路。
这些年来逐渐将我的音乐库迁移到了 Plex Media Server 上,因为之前部署的 Plex 是用了 Docker,迁移到独立主机之后想直接安装,所以想将之前的 Plex 数据迁移出来,直接恢复使用。
备份是一定要做的事情,为了数据安全。
通常 Plex 中的媒体文件都会用 [[Syncthing]] 来做一份备份冗余,但是 Plex Media Server 生成的媒体文件,包括 viewstates, metadata, settings 等等就需要直接去备份 Plex Media Server 的内容了。
在 Debian/Fedora/CentOS/Ubuntu 中:
/var/lib/plexmediaserver/Library/Application Support/Plex Media Server/
Plex 在本地使用 SQLite3 存储数据。
在 macOS 上:
~/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db
Windows 上:
"%LOCALAPPDATA%\Plex Media Server\Plug-in Support\Databases\com.plexapp.plugins.library.db"
在 Linux 上(包括 NAS):
$PLEX_HOME/Library/Application\ Support/Plex\ Media\ Server/Plug-in\ Support/Databases/com.plexapp.plugins.library.db
备份时不要对备份的数据进行任何修改,防止备份数据库出错。
如果修改了本地媒体文件的地址,需要更新数据库:
UPDATE `section_locations`
SET `root_path`=
REPLACE(`root_path`,
'/Old_PATH/',
'/NEW_PATH/')
WHERE `root_path` like '%Old_PATH%';
如果确定需要修改数据库中的路径,那么确保所有表中的路径都要修改。
如果只是升级磁盘,文件的目录没有变化,那么只需要在迁移之前停掉 Plex Media Server,然后升级完成之后再启动即可。
如果更改了媒体文件的路径,那么就需要多出几步。
Empty trash automatically after every scan
Scan Library Files
,服务器会检查新位置的文件内容,然后和已经有的媒体文件做关联