python程序化交易数据存储解决方案
翻到两个帖子:http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1020269,http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1078309
好奇心痒之下,自己也试着折腾了一下。(http://bbs.saraba1st.com/2b/thread-1289388-1-1.html
网上有的帖子主要是在win8和server2012的,win10和server2016的比较少,我自己试探了一些,分享一点经验~
主机是i5-4590,8g,浦科特M6s256G+希捷2T+东芝3Tx2,1511的win10 pro系统。这里的2016,都是指的server2016technical_preview_5_x64_dvd_8509035
首先是存储池:
总的来说,win8和server2012的存储池算老一代,win10和server2016算新一代。老一代的池可以被新一代系统识别并(可选)升级到新一代,但新一代的池无法被老一代系统识别,但同一代中也有少许区别和不兼容:
2012的池可被win10识别并升级为win10的,升级后无法再被2012识别
win10的池无法被2012识别
win10的池可被2016继承
2016的池无法被win10识别
新老两代的共同点:用物理硬盘组成存储池,存储池中建立虚拟硬盘(可选普通、镜像、奇偶校验),虚拟硬盘上再分区(即卷)。一个系统中可以建立多个池,一个池中可以有多个虚拟硬盘,一个虚拟硬盘中可以有多个分区。win10中,把虚拟磁盘和卷两层统一为一个存储空间(卷和虚拟盘一样大),但实际可以在磁盘管理中缩小卷、新建卷等。
win10必须把整块物理磁盘都加入存储池(会清空盘上所有数据),一块硬盘只能加入一个池;2012、2016可以只把物理磁盘中的未分配空间加入池(比如2T盘,建了0.5T分区,留1.5T未分配,就可以把1.5T加池),但必须把所有未分配空间都加入池(至少GUI里是这样,命令行不详)。
物理硬盘属于哪一个池,这个池中有哪些虚拟硬盘,分别由哪些物理磁盘组成,这些信息都存储在物理硬盘上的那一个MSR分区中,因此哪怕换台电脑插上,只要是支持该代存储池功能的windows都能识别,也无所谓插上顺序,只要插上最少足够读取该虚拟磁盘的物理磁盘,就可以读取其中数据。
新一代的存储池支持优化驱动器使用率(使数据在各个物理磁盘中均匀分布),老一代只能人工手动操作
8和10原生不带分层加速和dedup,2012和2016支持分层加速和dedup。分层加速:把ssd作为缓存,hot数据(读取100次以上)移动到ssd中,或者也可以手动指定移动哪些文件,类似混合硬盘。
几种虚拟磁盘格式:简单、奇偶校验的默认设置都非常傻逼。“简单”默认只有1列,也就是说raid0的坑爹抗风险能力,却没有raid0的速度(见下表的“简单1列”),类似磁盘管理中的跨区卷,要想读写能力上升必须需要用PowerShell指定列数为磁盘数才行(见下表的“简单2列”和“简单3列”,类似“带区卷”,即raid0,例:
New-VirtualDisk -StoragePoolFriendlyName “池byWin10” -FriendlyName “简单2列” -Size 1TB -ProvisioningType Thin -ResiliencySettingName simple -NumberOfColumns 2
复制代码
);奇偶校验默认只有3列且单奇偶校验,也就是说哪怕7个物理盘组默认奇偶也只有2/3的有效可用容量、且只容许死亡一块盘,要提升容量利用率和容许磁盘损坏量也必须用PowerShell指定列数和容许磁盘损坏量(例:
New-VirtualDisk -StoragePoolFriendlyName “池byWin10” -FriendlyName “双奇偶7列” -Size 1TB -ProvisioningType Thin -ResiliencySettingName “Parity” -PhysicalDiskRedundancy 2 -NumberOfColumns 7
复制代码
)。win10也可用上面的PowerShell命令建立双奇偶校验空间。镜像没什么好说的,基本可以认为是raid1。可以用下列命令查看虚拟磁盘的类型参数:
Get-VirtualDisk | ft @{Expression={$.FriendlyName}; Label=“昵称”},
@{Expression={$.ResiliencySettingName}; Label=“raid类型”},
@{Expression={$.NumberOfColumns}; Label=“列数”},
@{Expression={$.PhysicalDiskRedundancy}; Label=“物理磁盘允许损坏数”},
@{Expression={$.NumberOfDataCopies}; Label=“DataCopies数”},
@{Expression={$.ProvisioningType}; Label=“配置类型”},
@{Expression={$.Size / 1GB}; Label=“Size(GB)”},
@{Expression={$.FootprintOnPool / 1GB}; Label=“占用池空间(GB)”},
@{Expression={$_.writecachesize/ 1MB}; Label="回写缓存(MB)"} -AutoSize
复制代码
一块虚拟磁盘用到的物理磁盘数必须>=NumberOfColumns*NumberOfDataCopies,
虚拟磁盘类型 容量利用率
Number Of DataCopies
理论读取性能 Number Of Columns必须满足 Physical Disk Redundancy
n列简单
1
1
n*NumberOfDataCopies
n>=1
0
n列双向镜像 1/2
2
n*NumberOfDataCopies?(不确定,下同)
n>=1
1
n列三向镜像 1/3
3
n*NumberOfDataCopies?
n>=1
2
n列单奇偶
(n-1)/n
1
(n-1)*NumberOfDataCopies?
n>=3
1
n列双奇偶
(n-3)/n
1 (n-3)*NumberOfDataCopies? n>=7 2
2012里的双奇偶校验必须是固定容量类型的虚拟磁盘,但10和2016支持使用动态的
我用Crystal DiskMark测的速度
sequential
512k
4K
4K QD32
读
写
读
写
读
写
读
写
希捷2T
157.3
151.9
53.24
81.67
0.654
1.2
1.591
1.172
东芝3T一号 DT01ACA300
196.4
186.9
59.31
81.69
0.755
0.754
1.926
0.823
东芝3T二号 DT01ACA300
200.4
196
59.34
83.1
0.775
0.761
1.88
0.713
简单3列
520
506.1
60.89
88.23
0.857
2.076
4.634
2.134
简单2列
336.1
340.4
50.56
74.8
0.713
1.349
3.334
1.325
简单1列
187.2
196.4
65.13
109.3
0.824
1.028
2.813
1.084
双重镜像
195.9
181
64.73
75.41
0.805
0.649
4.579
0.662
奇偶3列
336
34.87
56.47
9.947
0.746
0.434
2.621
0.491
windows的双奇偶校验算法非常坑,磁盘容量利用率为(n-3)/n而不是(n-2)/n……
然后是dedup
是文件数据块级别的去重(两个1T的文件,只相差1byte,dedup后占用空间大约只有1T)。在dedup时吃几百近千MB的内存,dedup完毕后几乎不吃内存,我给2012虚拟机分配768MB内存足矣。dedup时磁盘读写大,但仅是速度慢,不阻止其它程序对文件的读写(操作是透明的)。不论对该类文件去重效果如何,把所有文件都转成专用的数据块(这一操作类似于复制后删除,对磁盘的读写也是,由此可估算速度:dedup速度约=同盘复制的速度),存在卷的根目录的System Volume Information里(隐藏不可见),文件原位置只留一个指针(占用空间很小)。所以如果把一个卷完全dedup后,理论上选中所有文件夹查看属性,大小是不变,占用空间应该变得很小(无论dedup率如何,因为产生的数据块都到那个隐藏文件夹里去了,这里看不到数据块的空间占用,这里占用空间的只有指针文件),一般不足1G(或者文件很多的话最多几个G)。
像http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1020269中84楼贴的图,大小2.28TB,占用670GB,实际上肯定是有600多G文件还未dedup(未转换为数据块),真正完成后占用应该是不到1G的。压缩率不是从这儿看的,而应该用“卷属性的已用空间”除以“全选、属性的总文件大小”。(无法查看特定文件或文件夹的压缩率,只能看整个卷的)
例如,我有个卷放的系统备份、Windows安装iso、Onenote备份等等杂物仓库,全选其中文件大小是40.5GB,占用空间是22.3MB;卷的已用空间是31.0GB,则去重率=(40.5-31)/40.5=23.5%
对视频文件效果很差(我对160G的电影、动画片视频试了下,只删去了0.5G),http://bbs.saraba1st.com/2b/forum.php?mod=viewthread&tid=1020269这帖子里14楼说
3.Dedup对ISO,VHD这种重复性比较高的文件去重率可以到90%,各种番各种老师也可以到50%。3T存储池实际可用空间超过10T。
有误不可信。iso、vhd去重率高是真,但是“各种番各种老师到50%”,我觉得99%的可能性是他存了两份文件(比如文件名不一样)自己不知道或者去重率计算方法不对。
win8.1可以用这个方法开启2012的dedup:http://wenzhongxiang.blog.51cto.com/6370734/1636286
win10有人用这个方法开启了2016的dedup,但是我照做失败了:http://arthurremy.com/index.php/ … ation-on-windows-10
2012的dedup无法在win10中识别,2016的dedup无法在win10、2012中识别。
2012、2016的dedup卷共享给win10是可以正常识别使用的。
——————————————————以下是2017.02.11更新——————————————————
之后不久就有个哥们也写了篇类似的:http://blog.sina.com.cn/s/blog_6a975f1d0102woe1.html,也挺详细,可以和我的互为补充。
他里面提到的很重要的一点:
1607的存储池不兼容1511,切记,切记。
即win10_1511的存储池可识别且升级为1607的,但1607的不能被1511识别。
之前有一个可以评估开启dedup可节约空间的小软件忘记介绍了:DDPEVAL ,
DDPEVAL D:
评估对D盘Deduplication的效果(开启后能节省多少空间等),方便我们选择是否应该开启Deduplication
另外,我一直觉得3个机械盘组成的奇偶校验的虚拟磁盘连续写入能力太差,经我后续折腾,发现了一个能提升3-5倍连续写入速度(从原先的35MB/s狂涨至165MB/s以上)的方法,代价是约1G内存。方法如下:
不要把物理磁盘直接加入存储池,而是在这些物理磁盘上分别各建一个VHDX文件(一般是和所在物理磁盘容量一样大或稍小一些,动态、静态的随便,我是懒就选的动态,反正速度只差一点),再把这个VHDX挂载、加入存储池。
安装PrimoCache软件,对VHDX文件所在的卷开启256MB以上(推荐1GB及以上)的一级缓存,缓存策略选“仅写”或“读写”(我选读写),延时写入选10秒或更长(我选10秒);高级设置中写入模式选“均衡”(非常重要!),勾上“写入后释放相应缓存”、“待机时刷入所有缓写数据”。
这样得到的奇偶校验虚拟磁盘,连续写入速度从原先的35MB/s狂涨至165MB/s以上,从SSD拷大文件到奇偶校验盘速度如图
代价就是“第2步中设置的一级缓存+额外的约500MB=起码750MB”内存、一点CPU性能(写入时CPU总使用率升到了38%,静止时是10%,即i5-4590约28%的使用率)以及内存缓写的断电风险(所以前面我只选了10秒延时,这个就不多展开讲了)。
注意,这是真正的连续写入速度,不是仅在内存缓存中写入,因为上面这图里已经拷了10多个G的数据、早已超出我设定的2G内存缓存了,开头那一段高速才是因为写入内存缓存造成的。