持续了一段时间在观察一些还在活跃系统的架构变化,从最早开始关注的tidb,到ozone,再到也一直持续在关注的presto,从中也发现了一些共同点。再结合最早的hadoop的设计,我们会发现架构的演变方向。
针对组件系统来说,大体上逻辑架构还是master-worker模式。或者说计算节点和存储节点分离的模式。
阅读全文…
行业技术框架发展的小共同点
作者: inter12
日期: 14 二月, 2023
没有评论 | 101 views
海龟交易法则读书笔记(第一二章)
作者: inter12
日期: 17 十月, 2021
没有评论 | 889 views
第一章:玩风险的交易者
导言:高风险,高回报,玩这个游戏是需要勇气的。
海龟的共同特征:具备赛局理论和策略方面的背景,对于概率学有研究
投资者:买东西是基于买入的东西的内在价值回上升,买股票买的是这家公司的管理层,产品和市场地位。股票反应的是企业的真实价值
投机者:关心价格,买卖的是风险
金融市场的价值:允许风险从一个参与者转移到另一个参与者
对冲:通过买卖期货合约来降低原材料价格变化或者外汇市场波动所嗲来的经营性风险。例如航空公司关心的是自己的航班运营,石油价格是非核心领域,所以可以通过对冲来降低风险。
风险交易
流动性风险:无法买入或者卖出的风险,例如房地产。
价格风险:价格大幅上升或者下降
流动性资产:能够快速、便捷转化为现金的资产。
价差:买入和卖出之间的价格差异。
帽客/市商:经营流动性风险的交易商
套利:帽客操作的交易,通常涉及两个不同市场的流动性
投机商/头寸交易商:通过将风险转移给交易者来规避价格风险
例如:ACME想买入石油期货来规避风险,涉及一下三个角色
对冲者:也就是ACME公司的交易者们
帽客:市场内的交易商,经营的是流动性风险。赚取买卖价差。现在电子交易场所的发展,帽客已经基本消失。
投机者:寄希望价格将来会下跌或者上涨的交易者
价格波动:取决于市场内所有买卖者的共同态度。
第二章:揭秘海龟思维
导言:在交易世界里,人类的情绪即是机会之所在,也是最大的调整。掌握了它,你就能成功。忽视它,你就危险了。
推荐书籍:罗伯特-希勒《非理性繁荣》,赫什-舍夫林《超越贪婪与恐惧》
大部分的交易不会理性交易。通常的情绪
希望:我希望买了之后立马涨
恐惧:我再也赔不起了,这次我躲的远远的
贪心:我赚翻了,我要把自己的寸头扩大一倍
绝望:这个交易系统不管用,我一直在赔钱
认知偏差
- 损失厌恶证:对于避免损失有强烈的偏好,不赔钱比赚钱更重要
- 损失的心理比赢利的大一倍或者更多
- 影响机械性交易
- 沉淀陈本效应:更重视已经花掉的前,而不是未来可能要花的钱
- 沉淀陈本,已经发生的,无法收回的陈本
- 例如某公司投入1亿研发A系统,后来发现B系统更正确,由于无法摆脱心理,继续坚持原来的决策
- 通常在群体决策中更明显
- 处理效应:早早兑现利润,却让算是持续下去
- 更倾向于卖掉已经赢利的股票,保留亏损的股票
- 无法方法赢利,通常无法止亏
- 结果偏好:只会更具一个决策的结果来判断它的好坏,而不取考虑决策本身的质量
- 过于重视已经发生的事情,忽视决策本身的过程及质量
- 正确的交易法则也有可能亏损
- 近期偏好:更重视近期的数据或经验,忽视早期的数据或经验
- 只关注近一个月或者一年的交易经验
- 近期不成功的交易会怀疑自身的方法和决策程序
- 锚定效应:过于依赖容易获取的信息
- 决策过于依赖一个过于容易获取的信息,盯着定期的一个价格,例如自身对于腾讯一直盯着700的价钱,没有重新建立锚点
- 潮流效应:盲目相信一件事,只因为其他许多人相信它
- 羊群效应,当大部分人都相信一件事情,所以就容易形成潮流效应
- 信奉小数法则:从太小的信息中得出没有依据的结论
- 需要相信大数据,而不是小数。一个基金经理要看他五年以上的交易收益
海龟方式
现在主流的几种交易风格
趋势跟踪
定义:通过分析过去几个月的大趋势,来判定市场是处于高位或者低位,如果市场逆转,而且逆趋势几周,那么就会退出。
问题:
- 大趋势很少出现,跟踪这种趋势的失败率远远大于成功率
- 趋势不仅在没有趋势的时候会失效,在逆趋势的时候也会失效
- 趋势跟踪法需要动用大量的资金来保障合理的风险控制
反趋势交易
当市场没有形成趋势时,反趋势交易者通过与趋势跟踪法想法的策略来交易。
例如交易者不是在新高时候买入,而是在价格接近新高的时候买空,依据是新高的突破通常不会引发市场趋势
波段交易
本质上同趋势跟踪是一样的,不过是短周期,例如几天或者几周。
喜欢用短期价格走势来做波段
当日交易法则
极端短期交易,避免夜间的负面影响明天的市场交易
波动定义
- 稳定平静:价格在一个很小的范围内波动
- 稳定波动:有大的日间或周间波动,没有月间波动
- 平静的趋势:价格在几个月中稳定、缓慢的上升或者下降
- 波动的趋势:在几个月中价格有大的变化,偶尔伴有剧烈的短期逆转
海龟交易者从来不去预测市场的动向,而是寻找市场处于某种特定状态的指示信号,基于信号来判断市场处在什么样的状态中。
时间戳实现
作者: inter12
日期: 10 六月, 2021
1 条评论 | 2,152 views
分布式事务中时间戳是非常关键的点,来解决版本控制和事务顺序。整理几种常见的时间戳机制。
Hybrid Logical Clock (HLC)
HLC 将时间戳分成物理(高位)和逻辑(低位)两部分,物理部分对应 UNIX 时间戳,逻辑部分对应 Lamport 时钟。在同一毫秒以内,物理时钟不变,而逻辑时钟就和 Lamport 时钟一样处理——每当发生信息交换(RPC)就需要更新时间戳,从而确保操作与操作之间能够形成一个偏序关系;当下一个毫秒到来时,逻辑时钟部分归零。
HLC 的正确性其实是由 Logical Clock 来保证的:它相比 Logical Clock 只是在每个毫秒引入了一个额外的增量,显然这不会破坏 Logical Clock 的正确性。但是,物理部分的存在将原本无意义的时间戳赋予了物理意义,提高了实用性。
缺陷:
可以保证同一个进程内部事件的时钟顺序,但是解决不了系统外事件发生的逻辑前后顺序与物理时间前后顺序的一致性,因此做不到Linearizability,也就做不到外部一致性。
行业公司:
YugabyteDB,Cockroach
TrueTime
可以做到外部一致性,同时能做到全球化部署。
可线性化:支持原子读取和写入操作的并发对象。
每个数据中心有若干个time master机器。大部分time master机器安装了GPS天线和接收器。剩下的time master机器安装了原子钟。time master之间会相互校验时间,如果某个time master发现自己的本地时间和其他time master相比差异很大,会把自己设置为离线,停止工作。客户端向多个time master查询,防止某个time master出现故障影响结果
行业公司
Google
TSO
全局集中式授时服务,对网络要求比较高,不能跨地域,理论上可以做到外部一致性;
TSO的全局版本号由 physical time + logical time 两个部分组成。
physical time :真实的时间戳,毫秒级
logical time:毫秒之外的逻辑时间
整体的方案是跟HLC差不多的。
TSO节点是位于PD模块,通过raft来保障可用性。
行业公司:
TIDB
springflux的初步体验
作者: inter12
日期: 8 四月, 2021
没有评论 | 2,172 views
webFlux和MVC的区别
Spring WebFlux 是一个无阻塞的Web 框架,它能够充分利用多核CPU 的硬件资源去处理大量的并发请求
Spring MVC 构建于Servlet API 之上,使用的是同步阻塞式I/O 模型,每一个请求对应一个线程去处理。
阅读全文…
记spring的XmlBeanFactory加载机制
作者: inter12
日期: 14 九月, 2020
没有评论 | 1,814 views
周日处理一个spring-security的问题。顺带把spring的类加载机制和spring的security也看了一遍。
觉得spring的整个设计还是蛮有意思的。用的spring是4.3.18,后续用到的源码也都是这个版本的。
阅读全文…
基于Junit的几个性能压测工具
作者: inter12
日期: 10 六月, 2020
没有评论 | 2,792 views
最近新写了一基于phoneix存储的系统,想做一下接口的压力测试
简单搜索了一下相关开源组件,找了几个不错的组件,都是基于junit整合的。ps: 搞Java的好处就是先去github找一下是否有成熟的组件,自己写太累,也不完善。
先说结论:如果你的框架没有强制依赖guava的话,那么选哪个都可以,如果强制依赖了guava的话,那么用com.github.javatlacati » contiperf
目前找了几个 :
junitperf » junitperf。最近一直更新已经是2005年了,应该早不维护了。
com.github.noconnor » junitperf : 最新的是这个2019年,最新版本是1.15.0 ,目前是支持junit5
com.github.javatlacati » contiperf : 2019年还在更新,基于junit4,它的前身是org.databene » contiperf 不过最近更新也是在2014年了
com.github.houbb » junitperf : 2020年更新,底层依赖的是 com.github.noconnor » junitperf和com.github.javatlacati » contiperf ,是对于两者的重新包装。 目前是支持junit5
组件对比
组件
|
noconnor » junitperf
|
javatlacati » contiperf
|
houbb » junitperf
|
最新junit版本
|
5
|
4
|
5
|
输出报告
|
console,html,csv,custom,multiple
|
html
|
console,html,csv,custom,multiple
|
指标
|
吞吐、min、max、avg、success、error
|
吞吐、min、max、avg、med、90线
|
同noconnor » junitperf
|
定制指标
|
可以随意定制90线,95线等指标
|
可以随意定制90线,95线等指标
|
可以随意定制90线,95线等指标
|
多线程
|
支持
|
支持
|
支持
|
结果预期
|
支持
|
支持
|
支持
|
输出
|
通过JUnitPerfRule定义
|
通过标注 report定义
|
|
参数
|
丰富
|
丰富
|
有裁剪,没有所有都支持
|
从更新时间来说,junitperf比较持续,而且功能上也没有什么区别,就采用了junitperf来做junit的集成性能测试。
houbb » junitperf 其实是包装了 noconnor » junitperf 和javatlacati » contiperf 。 是一个封装器,也改写了使用方法。
使用姿势
noconnor » junitperf的使用姿势
public class PerformanceTest { //定义输出模式,CsvReportGenerator,HtmlReportGenerator,CustomStatisticsCalculatorImpl,CustomStatisticsCalculatorImpl @Rule public JUnitPerfRule perfTestRule = new JUnitPerfRule(new ConsoleReportGenerator()); /** * threads :执行线程数 * durationMs :执行时间 * rampUpPeriodMs:平滑预热时间,默认是精致 * warmUpMs : 准备时间 * maxExecutionsPerSecond:每秒执行个数 * @throws InterruptedException */ @Test @JUnitPerfTest(threads = 50, durationMs = 125_000, rampUpPeriodMs = 2_000, warmUpMs = 10_000, maxExecutionsPerSecond = 11_000) public void test() throws InterruptedException { System.out.println("haha"); ThreadLocalRandom current = ThreadLocalRandom.current(); TimeUnit.SECONDS.sleep(current.nextInt(10)); } }
houbb » junitperf 使用姿势
/** * @author lukexue * @create 2020-06-10 15:02 **/ public class PerformanceTest2 { /** * 配置:2个线程运行。准备时间:1000ms。运行时间: 2000ms。 * 要求:最快不可低于 210ms, 最慢不得低于 250ms, 平均不得低于 225ms, 每秒运行次数不得低于 4 次。 * 20% 的数据不低于 220ms, 50% 的数据不得低于 230ms; * reporter : 输出格式html */ @Test @JunitPerfConfig(threads = 50, warmUp = 10000, duration = 125000, reporter = {ConsoleReporter.class}) //ConsoleReporter,HtmlReporter @JunitPerfRequire(min = 210, max = 250, average = 225, timesPerSecond = 4, percentiles = {"20:220", "50:230"}) public void test() throws InterruptedException { System.out.println("haha"); ThreadLocalRandom current = ThreadLocalRandom.current(); TimeUnit.SECONDS.sleep(current.nextInt(10)); } }
结果输出
最终结果输出
</div> <div>15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Started at: 2020-06-10 15:07:26.854 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Invocations: 1340 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Success: 1340 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Errors: 0 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Thread Count: 50 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Warm up: 10000ms 15:09:31.976 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Execution time: 125000ms 15:09:31.977 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Throughput: 11/s (Required: 4/s) - PASSED 15:09:31.978 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Min latency: 0.003639ms (Required: 210.0ms) - PASSED 15:09:31.978 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Max latency: 9005.115ms (Required: 250.0ms) - FAILED 15:09:31.979 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Ave latency: 4351.276ms (Required: 225.0ms) - FAILED 15:09:31.979 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Percentile: 50% 4004.3013ms (Required: 230.0ms) - FAILED 15:09:31.980 [main] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Percentile: 20% 1004.48737ms (Required: 220.0ms) - FAILED 15:09:31.982 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Started at: 2020-06-10 15:07:26.854 15:09:31.982 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Invocations: 1340 15:09:31.982 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Success: 1340 15:09:31.982 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Errors: 0 15:09:31.982 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Thread Count: 50 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Warm up: 10000ms 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Execution time: 125000ms 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Throughput: 11/s (Required: 4/s) - PASSED 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Min latency: 0.003639ms (Required: 210.0ms) - PASSED 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Max latency: 9005.115ms (Required: 250.0ms) - FAILED 15:09:31.983 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Ave latency: 4351.276ms (Required: 225.0ms) - FAILED 15:09:31.984 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Percentile: 50% 4004.3013ms (Required: 230.0ms) - FAILED 15:09:31.984 [pool-2-thread-1] INFO com.github.houbb.junitperf.core.report.impl.ConsoleReporter - Percentile: 20% 1004.48737ms (Required: 220.0ms) - FAILED</div> </div> <div>
唯一的遗憾是包是强依赖与 guava,如果你自己用了guava版本比它还低的话就跑不起来,因为我的业务也用了hbase,里面依赖的低版本的guava,结果很尴尬。这个也是java的问题
参考资料:
https://segmentfault.com/a/1190000015722861
https://github.com/houbb/junitperf
https://github.com/noconnor/JUnitPerf#multiple-reports
yarn 设计之 Dispatcher
作者: inter12
日期: 10 十二月, 2019
没有评论 | 2,548 views
Dispatcher是yarn代码中使用场景比较多的一个类,整体的设计思路是一个生产者和消费者模型,不过支持的多生产者和多消费者的模式。
不同的生产者和消费者之间通过一个Map<Class<? extends Enum>, EventHandler> eventDispatchers 来映射,数据传递通过一个无界的BlockingQueue来持有,消费是启动一个Thread来做处理。Thread是同步的根据注册的类型,切换不同的handler来处理,这个过程是同步的。
所有的handler实现EventHandler接口或者是MultiListenerHandler,MultiListenerHandler的实现是为了满足一个事件有不同的事件通知,其中EventHandler是一对一的消息模型,MultiListenerHandler是一对多的消息模型。
事件继承AbstractEvent类
具体实现上有 MultiThreadedDispatcher、AsyncDispatcher两种
AsyncDispatcher:单线程的事件生产和消费消息
MultiThreadedDispatcher : 持有多个AsyncDispatcher,也就是一个AsyncDispatcher集合,添加事件时候通过轮训的方式添加到对应的AsyncDispatcher中,每个AsyncDispatcher维护自己的异步消费线程。
落地的场景有以下几种:
ResourceManager — AsyncDispatcher
————————————————
注册的事件类型 –> 事件的处理类RMAppEventType –> ApplicationEventDispatcherRMAppAttemptEventType –> ApplicationAttemptEventDispatcherNodesListManagerEventType –> NodesListManagerSchedulerEventType –> SchedulerEventDispatcherRMNodeEventType –> NodeEventDispatcherRMAppManagerEventType –> RMAppManagerAMLauncherEventType –> ApplicationMasterLauncherRMFatalEventType –> ResourceManager.RMFatalEventDispatcher
RMApplicationHistoryWriter — MultiThreadedDispatcher
————————————————
WritingHistoryEventType –> ForwardingEventHandlerdispatcher个数 :yarn.resourcemanager.history-writer.multi-threaded-dispatcher.pool-size=10
SystemMetricsPublisher — MultiThreadedDispatcher
————————————————
SystemMetricsEventType –> ForwardingEventHandlerdispatcher个数 :yarn.resourcemanager.system-metrics-publisher.dispatcher.pool-size=10
CommonNodeLabelsManager — AsyncDispatcher
————————————————
NodeLabelsStoreEventType –> ForwardingEventHandler
NodeManager — AsyncDispatcher
————————————————
ContainerManagerEventType –> ContainerManagerImplNodeManagerEventType –> NodeManager
ContainerManagerImpl — AsyncDispatcher
————————————————
ContainerEventType –> ContainerEventDispatcherApplicationEventType –> ApplicationEventDispatcherLocalizationEventType –> ResourceLocalizationServiceContainersMonitorEventType –> ContainersMonitorContainersLauncherEventType –> ContainersLauncherLogHandlerEventType –> LogHandlerSharedCacheUploadEventType –> SharedCacheUploadService
ResourceLocalizationService 复用的是ContainerManagerImpl的AsyncDispatcher
————————————————
LocalizerEventType –> LocalizerTracker
如果发现AsyncDispatcher 异步下发性能不够的话,一般会看到这个日志
Size of event-queue is 1000
Size of event-queue is 2000
说明下游的handler处理性能不行了
原生的日志里面有一个问题,不好的点就是 不知道是哪块的逻辑处理性能不行,日志只到AsyncDispatcher级别,有点烦人
slf4j + log4j + commons log 的相关配置
作者: inter12
日期: 19 八月, 2019
没有评论 | 2,675 views
之前一直没有系统的整理 日志依赖相关的包,最近恰好查一个问题,需要在一个最简单的环境下,打印日志。就花了点时间整理了一下各个日志包之间的使用关系。
阅读全文…
hdfs-namenode之间自动ha切换过程
作者: inter12
日期: 17 四月, 2019
没有评论 | 4,478 views
整个namenode之间的ha保证是通过ZKFC这个组件来完成的。
阅读全文…