1. 多线程保存数据到数据库
> 语句:INSERT INTO 目标表 SELECT * FROM 来源表 ; 也可以先查询出结果保存下来,再把保存的值放到insert语句。 MySQL 是一个关系型数据库,目前属于 Oracle 旗下公司。MySQL是开放源码软件,因此可以大大降低总体拥有成本。支持多线程,充分利用CPU资源。提供TCP/IP、ODBC和JDBC等多种数据库连接途径。支持大型的数据库。可以处理拥有上千万条记录的大型数据库
2. 多线程存储数据
回答这个问题的关键是,“
回测和研究会用到这些数据,有一定的查询需求
”。如果只是存储50T的数据,有很多种方法:(1)用二进制文件分日期分股票存储,(2)使用sql server,pg这样支持分区表的事务型数据库,(3)使用hive这样的离线数据仓库,(4)用Greenplum这样的开源或商业MPP数据仓库,(5)kdb+和DolphinDB这样的专业时序数据库。
选择一种合适的存储方法是为了更好的读取和利用这些数据。一般需要考虑以下几个方面的问题:
数据开发和建模是不是方便
如果只是简单按照日期和股票代码来查询tick data,基本上所有方法都可以用。(2)和(3)速度会比较慢。(1)需要自己来编程。
如果需要数据过滤,聚合(譬如按时间精度聚合),多表连接,(4)和(5)是最方便的,性能也不错。
如果需要更为专业的时间序列数据处理和建模,譬如rollup,sliding functions,window function,window join, asof join,pivot等,选(5),用其他系统都不是很方便。
另外说一下,kdb+的学习曲线比较陡峭。
是否需要用到分布式计算
虽然总的数据量很大,但是每次计算的数据量都不大,问题就会简单很多,基本上5种方法都可以使用。但是如果需要建模的数据量很大,涉及很多天,很多股票,用到的维度又很多,譬如在几十亿行数据上对几十个上百个变量跑回归,或者说分区字段和group字段不一致的时候做聚合分析,都会涉及到分布式计算,Greenplum和DolphinDB支持的比较好,支持库内计算,不需要移动数据,速度很快。其它的存储方法可以考虑写一个跟通用计算引擎spark的适配器,然后用spark来实现分布式SQL和分布式机器学习,但性能上会不库内计算差不少。
开发和建模过程中是否容易引入bug和错误
如果自己要写很多代码,不仅时间成本很高,而且极易引入错误。null数据的处理,多线程的处理,多个数据源的连接都很容易引入bug。
如果涉及到分布式计算,或者需要多次迭代,数据本身有可能是动态变化的,数据的一致性也要注意。一般数据仓库本身提供的库内计算,能提供快照级别的隔离,保证计算过程总用到的所有数据是一致的。Greenplum和DolphinDB都支持快照级别隔离。Spark不能工作在动态数据上。
运行效率如何
回测和研究虽然对实时性要求不高,但运行效率还是很重要的。因为研究的成功率很低,尝试了几百个想法后,才可能有一个能成功。每个idea测试的时候,你可能需要尝试很多个参数组合。所以,如果运行效率不高,非常影响研究效率。(5)中的kdb+和DolphinDB无疑是所有方案中效率最高的。
如果是机构商用,你的竞争对手用什么
很多交易策略,尤其是套利类的策略scale可能不是很好,用的人很多了,价格和价值就趋于均衡,机会就没了。所以你要赶在你的对手之前。
根据你的需求,简单总结一下,
如果没有太多的预算,建议使用Greenplum + Spark
,但是两者都是通用的数据仓库和计算引擎,天然缺少时序数据和金融的基因,有些场景用起来不是很方便,一些本来很好的idea,可能因为实现太麻烦就放弃了。如果有足够的预算,建议使用专业的时序数据库
DolphinDB
或kdb+。顺便说一下,kdb+对分布式的支持很弱,面对40~50T的数据,你可能要搞一台非常暴力的服务器才能解决。3. 多线程导入数据
导入时类名写错了,首字母没有大写,应该改为import java.util.Scanner; java.util.Scanner 类是一个简单的文本扫描器可以分析基本类型和字符串使用正则表达式。以下是关于扫描器的要点: 一个扫描器使用分隔符模式分解它的输入,默认情况下与空白匹配。 扫描操作可能阻塞等待输入。 扫描器是不是安全的,无需外部同步多线程使用。
4. 多线程保存数据到数据库中
方法/步骤分步阅读
1创建新的工程项目,在项目中添加SharedPreferences测试Activity界面
2要是用SharedPreferences需要先获取SharedPreferences对象,不过在开发过程中所有的SharedPreferences都需要通过Context上下文对象创建,用户无法直接通过new创建SharedPreferences对象
3在Context获取SharedPreferences对象是要求传递两个参数,第一个是该对象的名称,第二个是创建的模式,通常都用私有模式,这样其他的应用就无法读取本应用的数据。还有其他的世界模式、多进程模式都因为存在数据安全性问题,已经被废弃,以后都可以不再使用了。
4SharedPreferences的需要通过edit()方法获取编辑器对象来添加和删除数据,读取数据时不需要通过编辑器对象,编辑器对象内部会做排序操作,防止多线程并发访问导致数据不一致。
5SharedPreferences的数据实际上是保存在磁盘的xml文件中,因而在使用编辑器对象增加或删除对象时会有提交操作,也就是把数据写入到磁盘上,磁盘IO操作相对于CPU运算和内存读写要慢很多,因而提交操作分成了两种方式。
6SharedPreferences在使用edit()方法获取到编辑器对象后还需要提交添加和删除数据操作,提交分为apply()和commit()两种方式,apply()方式底层是异步将数据写入到磁盘上,程序等待的时间比较短,commit()方法会等到数据全部写到磁盘上再返回,等待时间稍长,因此通常建议使用apply()方法提交SharedPreferences的更新。
7SharedPreferences还可以监听内容的变化,假如界面的展示需要和最新的数据保持一致可以在监听其中更新的界面内容
5. 多线程导出数据保证有序
p盘调线程具体办法是一种方法就是尽量将完全随机写变成有序的跳跃随机写。实现方式,可以是简单的在内存中缓存一段时间,然后排序,使得在 写盘的时候,不是完全随机的,而是使得磁盘磁头的移动只向一个方向。根据测试,再一次让我震惊,简单的先在内存中排序,竟然直接使得写盘时间缩短到1645秒,磁盘的r/s也因此提升到1000以上。写盘的速度,一下子提高了5倍。
- 相关评论
- 我要评论
-