Jul
1
UPDATE@2013.08.04 搞到了一批折扣邀请码,有兴趣的同学(最好是带项目的团队、公司等)可以联系我。
最近弄了一台 ucloud.cn 的vps。准确地说应该是云主机,跟我在别处买的vps的确是有些不同的地方。
首先是注册,ucloud对密码的安全性要求太高了。其实很早之前就拿到邀请码试用过三天,但是由于对密码的要求过于复杂,刚开始几次,每次登陆之前都得重置密码,比较蛋疼;后来终于记住了,相当不容易。
然后是选配置。ucloud的最低配置是单核、2G内存、2mbps单线,显然不是面向个人vps玩家了,不过对于创业公司什么的倒是很合适。对比了一下国内另外两家云主机的同样配置,价格上也还是挺有优势的。选配置的时候有个“高性能磁盘”选项很有意思,目测是为了数据库之类对磁盘IOPS要求比较高的场合设置的,勾上了价格也没多大变化。
最终我选择的配置是双核、2G、20GB数据盘、4M双线,2700/yr。
开通主机以后就是选择系统。我图省事选了个ubuntu 12.04 64bit的。本来还做好准备像我的个人vps那样,vnc连上去在命令行下通过mount上去的iso安装,结果发现等了一会儿直接就可以开始用了,看起来应该是像openvz方案一样事先准备好了对应的template改改配置就能上。而且非常贴心的一点是,apt的默认源是ucloud自建的同步源,apt-get update和install的时候就很爽~其他的OS没试过,不过去mirror看了下,除了ubuntu,还有debian、fedora、centos等发行版的源,甚至还有个10gen(也就是mongodb他们家)的源。
进入后台管理看了下,一眼就能认出浓浓的bootstrap的味道,感觉挺无趣的,好歹用个Flat UI什么的换换小清新的口味嘛-。- 不过后台功能还是挺赞的,尤其是与 upyun、dnspod 的战略合作,可以绑定他们两家帐号,方便管理。至于upyun/dnspod的牛逼之处就不用多说了,这三家能合力打造这样的平台,前景我非常看好。
开通的时候我选择的是华东双线机房,所以给分配了2个ip,一个电信一个联通,因为域名是托管在dnspod,可以为不同请求线路返回合适的ip,很给力。ping了一下,延迟只有11ms,相当不错。ssh登上去看了下,ifconfig只看到了个内网ip,还觉得挺神奇的。后来在ucloud的主页看到,这是他们的“弹性IP”解决方案,ip不是直接绑定在vps的网卡上。设想,对于线上4台年付费的web机器进行负载均衡,某一台down了,可以马上把另一个按小时付费的备机开起来,把ip切过去,这样即减少了故障时间,又相当节省,貌似不错。
所谓“云主机”,我觉得跟传统vps/服务器的主要区别有2个:一个是可以按需选择合适的配置,并且此后还可以不断调整升级且代价很小;另一个就是底层存储是基于网络的,所在服务器挂掉也不用担心,换个地方再启动起来就好了。
去年12月在杭州参加SegmentFault举办的Hackathon的时候曾经试用过XX云的主机,他们家的特色是有自建的BGP骨干网,网络比较给力;但问题是,XX云主机的磁盘IO烂到一定境界,实在是……后来听说他们是直接用NFS作为底层存储,以及看到各种吐槽他们家IO的……
所以这次用ucloud的时候就特意关注了下磁盘性能,跑点数据列出来附在后面供参考,可以看出性能相当不错,已fio的数据为参考,顺序读取697M,顺序写入419M,随机读取 6245 IOPS,随机写入 309 IOPS。其中随机写入偏弱,可能是多备份网络延迟的原因吧,不知道选择“高性能磁盘”效果会怎样,但是就算是309 IOPS,也比服务器用的机械硬盘快多了,跟别说被甩开n条街的XX云了……很好奇他们家这个是怎么实现的,真希望ucloud的技术团队可以分享一下经验~
至于ucloud的其他方面,因为用的时间还比较短,体验不多,没什么可说的,就是总体感觉良好。ucloud提供的这项服务,对于创业团队什么的来说,的确可以算是最合适的选择了。
下附磁盘测试数据:
TEST#1 dd写入
TEST#2 hdparm -tT
TEST #3 fio random-read
TEST #4 fio random-write
$ cat random-write-test.fio
[random-write]
rw=randwrite
size=1G
directory=/home/felix021/test/
$ fio random-write-test.fio
random-write: (g=0): rw=randwrite, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-write: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1): [w] [92.5% done] [0K/1429K /s] [0 /348 iops] [eta 01m:09s]
random-write: (groupid=0, jobs=1): err= 0: pid=10733
write: io=1024.0MB, bw=1236.3KB/s, iops=309 , runt=848202msec
clat (usec): min=1 , max=1101.4K, avg=3231.07, stdev=10586.16
lat (usec): min=1 , max=1101.4K, avg=3231.53, stdev=10586.42
bw (KB/s) : min= 14, max=397248, per=95.34%, avg=1178.40, stdev=9976.63
cpu : usr=0.19%, sys=0.75%, ctx=49240, majf=0, minf=24
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=0/262144/0, short=0/0/0
lat (usec): 2=0.01%, 4=0.06%, 10=54.82%, 20=25.75%, 50=2.45%
lat (usec): 100=1.28%, 250=0.84%, 500=0.36%, 750=0.08%, 1000=0.02%
lat (msec): 2=0.04%, 4=0.05%, 10=0.29%, 20=8.87%, 50=4.58%
lat (msec): 100=0.47%, 250=0.02%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec): 2000=0.01%
Run status group 0 (all jobs):
WRITE: io=1024.0MB, aggrb=1236KB/s, minb=1265KB/s, maxb=1265KB/s, mint=848202msec, maxt=848202msec
Disk stats (read/write):
vdb: ios=1/145156, merge=0/13152, ticks=12/3297360, in_queue=3297220, util=99.78%
TEST #5 fio sequence-read
TEST #6 fio sequence-write
最近弄了一台 ucloud.cn 的vps。准确地说应该是云主机,跟我在别处买的vps的确是有些不同的地方。
首先是注册,ucloud对密码的安全性要求太高了。其实很早之前就拿到邀请码试用过三天,但是由于对密码的要求过于复杂,刚开始几次,每次登陆之前都得重置密码,比较蛋疼;后来终于记住了,相当不容易。
然后是选配置。ucloud的最低配置是单核、2G内存、2mbps单线,显然不是面向个人vps玩家了,不过对于创业公司什么的倒是很合适。对比了一下国内另外两家云主机的同样配置,价格上也还是挺有优势的。选配置的时候有个“高性能磁盘”选项很有意思,目测是为了数据库之类对磁盘IOPS要求比较高的场合设置的,勾上了价格也没多大变化。
最终我选择的配置是双核、2G、20GB数据盘、4M双线,2700/yr。
开通主机以后就是选择系统。我图省事选了个ubuntu 12.04 64bit的。本来还做好准备像我的个人vps那样,vnc连上去在命令行下通过mount上去的iso安装,结果发现等了一会儿直接就可以开始用了,看起来应该是像openvz方案一样事先准备好了对应的template改改配置就能上。而且非常贴心的一点是,apt的默认源是ucloud自建的同步源,apt-get update和install的时候就很爽~其他的OS没试过,不过去mirror看了下,除了ubuntu,还有debian、fedora、centos等发行版的源,甚至还有个10gen(也就是mongodb他们家)的源。
进入后台管理看了下,一眼就能认出浓浓的bootstrap的味道,感觉挺无趣的,好歹用个Flat UI什么的换换小清新的口味嘛-。- 不过后台功能还是挺赞的,尤其是与 upyun、dnspod 的战略合作,可以绑定他们两家帐号,方便管理。至于upyun/dnspod的牛逼之处就不用多说了,这三家能合力打造这样的平台,前景我非常看好。
开通的时候我选择的是华东双线机房,所以给分配了2个ip,一个电信一个联通,因为域名是托管在dnspod,可以为不同请求线路返回合适的ip,很给力。ping了一下,延迟只有11ms,相当不错。ssh登上去看了下,ifconfig只看到了个内网ip,还觉得挺神奇的。后来在ucloud的主页看到,这是他们的“弹性IP”解决方案,ip不是直接绑定在vps的网卡上。设想,对于线上4台年付费的web机器进行负载均衡,某一台down了,可以马上把另一个按小时付费的备机开起来,把ip切过去,这样即减少了故障时间,又相当节省,貌似不错。
所谓“云主机”,我觉得跟传统vps/服务器的主要区别有2个:一个是可以按需选择合适的配置,并且此后还可以不断调整升级且代价很小;另一个就是底层存储是基于网络的,所在服务器挂掉也不用担心,换个地方再启动起来就好了。
去年12月在杭州参加SegmentFault举办的Hackathon的时候曾经试用过XX云的主机,他们家的特色是有自建的BGP骨干网,网络比较给力;但问题是,XX云主机的磁盘IO烂到一定境界,实在是……后来听说他们是直接用NFS作为底层存储,以及看到各种吐槽他们家IO的……
所以这次用ucloud的时候就特意关注了下磁盘性能,跑点数据列出来附在后面供参考,可以看出性能相当不错,已fio的数据为参考,顺序读取697M,顺序写入419M,随机读取 6245 IOPS,随机写入 309 IOPS。其中随机写入偏弱,可能是多备份网络延迟的原因吧,不知道选择“高性能磁盘”效果会怎样,但是就算是309 IOPS,也比服务器用的机械硬盘快多了,跟别说被甩开n条街的XX云了……很好奇他们家这个是怎么实现的,真希望ucloud的技术团队可以分享一下经验~
至于ucloud的其他方面,因为用的时间还比较短,体验不多,没什么可说的,就是总体感觉良好。ucloud提供的这项服务,对于创业团队什么的来说,的确可以算是最合适的选择了。
下附磁盘测试数据:
TEST#1 dd写入
引用
$ dd if=/dev/zero bs=1M count=4096 of=test
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 15.1328 s, 284 MB/s
4096+0 records in
4096+0 records out
4294967296 bytes (4.3 GB) copied, 15.1328 s, 284 MB/s
TEST#2 hdparm -tT
引用
$ for i in 1 2 3; do sudo hdparm -tT /dev/vdb; done
/dev/vdb:
Timing cached reads: 9574 MB in 2.00 seconds = 4790.56 MB/sec
Timing buffered disk reads: 1714 MB in 3.02 seconds = 568.37 MB/sec
/dev/vdb:
Timing cached reads: 10018 MB in 2.00 seconds = 5013.55 MB/sec
Timing buffered disk reads: 1840 MB in 3.01 seconds = 611.33 MB/sec
/dev/vdb:
Timing cached reads: 9574 MB in 2.00 seconds = 4792.34 MB/sec
Timing buffered disk reads: 1908 MB in 3.00 seconds = 635.80 MB/sec
/dev/vdb:
Timing cached reads: 9574 MB in 2.00 seconds = 4790.56 MB/sec
Timing buffered disk reads: 1714 MB in 3.02 seconds = 568.37 MB/sec
/dev/vdb:
Timing cached reads: 10018 MB in 2.00 seconds = 5013.55 MB/sec
Timing buffered disk reads: 1840 MB in 3.01 seconds = 611.33 MB/sec
/dev/vdb:
Timing cached reads: 9574 MB in 2.00 seconds = 4792.34 MB/sec
Timing buffered disk reads: 1908 MB in 3.00 seconds = 635.80 MB/sec
TEST #3 fio random-read
引用
$ cat random-read-test.fio
[random-read]
rw=randread
size=1g
directory=/home/felix021/test/
$ fio random-read-test.fio
random-read: (g=0): rw=randread, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1): [r] [100.0% done] [26789K/0K /s] [6540 /0 iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=10676
read : io=1024.0MB, bw=24980KB/s, iops=6245 , runt= 41976msec
clat (usec): min=77 , max=35439 , avg=155.44, stdev=237.39
lat (usec): min=78 , max=35440 , avg=155.82, stdev=237.39
bw (KB/s) : min=18384, max=28256, per=100.22%, avg=25035.02, stdev=1702.27
cpu : usr=3.42%, sys=23.48%, ctx=262433, majf=0, minf=24
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=262144/0/0, short=0/0/0
lat (usec): 100=3.05%, 250=93.84%, 500=2.44%, 750=0.22%, 1000=0.10%
lat (msec): 2=0.23%, 4=0.07%, 10=0.05%, 20=0.01%, 50=0.01%
Run status group 0 (all jobs):
READ: io=1024.0MB, aggrb=24980KB/s, minb=25579KB/s, maxb=25579KB/s, mint=41976msec, maxt=41976msec
Disk stats (read/write):
vdb: ios=260955/11, merge=0/10, ticks=25956/396, in_queue=25972, util=61.22%
[random-read]
rw=randread
size=1g
directory=/home/felix021/test/
$ fio random-read-test.fio
random-read: (g=0): rw=randread, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1): [r] [100.0% done] [26789K/0K /s] [6540 /0 iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=10676
read : io=1024.0MB, bw=24980KB/s, iops=6245 , runt= 41976msec
clat (usec): min=77 , max=35439 , avg=155.44, stdev=237.39
lat (usec): min=78 , max=35440 , avg=155.82, stdev=237.39
bw (KB/s) : min=18384, max=28256, per=100.22%, avg=25035.02, stdev=1702.27
cpu : usr=3.42%, sys=23.48%, ctx=262433, majf=0, minf=24
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=262144/0/0, short=0/0/0
lat (usec): 100=3.05%, 250=93.84%, 500=2.44%, 750=0.22%, 1000=0.10%
lat (msec): 2=0.23%, 4=0.07%, 10=0.05%, 20=0.01%, 50=0.01%
Run status group 0 (all jobs):
READ: io=1024.0MB, aggrb=24980KB/s, minb=25579KB/s, maxb=25579KB/s, mint=41976msec, maxt=41976msec
Disk stats (read/write):
vdb: ios=260955/11, merge=0/10, ticks=25956/396, in_queue=25972, util=61.22%
TEST #4 fio random-write
$ cat random-write-test.fio
[random-write]
rw=randwrite
size=1G
directory=/home/felix021/test/
$ fio random-write-test.fio
random-write: (g=0): rw=randwrite, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-write: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1): [w] [92.5% done] [0K/1429K /s] [0 /348 iops] [eta 01m:09s]
random-write: (groupid=0, jobs=1): err= 0: pid=10733
write: io=1024.0MB, bw=1236.3KB/s, iops=309 , runt=848202msec
clat (usec): min=1 , max=1101.4K, avg=3231.07, stdev=10586.16
lat (usec): min=1 , max=1101.4K, avg=3231.53, stdev=10586.42
bw (KB/s) : min= 14, max=397248, per=95.34%, avg=1178.40, stdev=9976.63
cpu : usr=0.19%, sys=0.75%, ctx=49240, majf=0, minf=24
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=0/262144/0, short=0/0/0
lat (usec): 2=0.01%, 4=0.06%, 10=54.82%, 20=25.75%, 50=2.45%
lat (usec): 100=1.28%, 250=0.84%, 500=0.36%, 750=0.08%, 1000=0.02%
lat (msec): 2=0.04%, 4=0.05%, 10=0.29%, 20=8.87%, 50=4.58%
lat (msec): 100=0.47%, 250=0.02%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec): 2000=0.01%
Run status group 0 (all jobs):
WRITE: io=1024.0MB, aggrb=1236KB/s, minb=1265KB/s, maxb=1265KB/s, mint=848202msec, maxt=848202msec
Disk stats (read/write):
vdb: ios=1/145156, merge=0/13152, ticks=12/3297360, in_queue=3297220, util=99.78%
TEST #5 fio sequence-read
引用
$ cat read-test.fio
[random-read]
rw=read
size=1g
directory=/home/felix021/test/
$ fio read-test.fio
random-read: (g=0): rw=read, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1)
random-read: (groupid=0, jobs=1): err= 0: pid=10798
read : io=1024.0MB, bw=697191KB/s, iops=174297 , runt= 1504msec
clat (usec): min=0 , max=16300 , avg= 4.73, stdev=97.89
lat (usec): min=1 , max=16300 , avg= 4.95, stdev=97.89
bw (KB/s) : min=615400, max=779152, per=99.97%, avg=696994.67, stdev=81877.45
cpu : usr=11.44%, sys=57.75%, ctx=3787, majf=0, minf=26
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=262144/0/0, short=0/0/0
lat (usec): 2=66.20%, 4=31.16%, 10=0.58%, 20=0.15%, 50=0.28%
lat (usec): 100=0.63%, 250=0.89%, 500=0.07%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%
Run status group 0 (all jobs):
READ: io=1024.0MB, aggrb=697191KB/s, minb=713924KB/s, maxb=713924KB/s, mint=1504msec, maxt=1504msec
Disk stats (read/write):
vdb: ios=3697/0, merge=0/0, ticks=1280/0, in_queue=1268, util=74.56%
[random-read]
rw=read
size=1g
directory=/home/felix021/test/
$ fio read-test.fio
random-read: (g=0): rw=read, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
random-read: Laying out IO file(s) (1 file(s) / 1024MB)
Jobs: 1 (f=1)
random-read: (groupid=0, jobs=1): err= 0: pid=10798
read : io=1024.0MB, bw=697191KB/s, iops=174297 , runt= 1504msec
clat (usec): min=0 , max=16300 , avg= 4.73, stdev=97.89
lat (usec): min=1 , max=16300 , avg= 4.95, stdev=97.89
bw (KB/s) : min=615400, max=779152, per=99.97%, avg=696994.67, stdev=81877.45
cpu : usr=11.44%, sys=57.75%, ctx=3787, majf=0, minf=26
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=262144/0/0, short=0/0/0
lat (usec): 2=66.20%, 4=31.16%, 10=0.58%, 20=0.15%, 50=0.28%
lat (usec): 100=0.63%, 250=0.89%, 500=0.07%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%
Run status group 0 (all jobs):
READ: io=1024.0MB, aggrb=697191KB/s, minb=713924KB/s, maxb=713924KB/s, mint=1504msec, maxt=1504msec
Disk stats (read/write):
vdb: ios=3697/0, merge=0/0, ticks=1280/0, in_queue=1268, util=74.56%
TEST #6 fio sequence-write
引用
$ cat write-test.fio
[random-read]
rw=write
size=1g
directory=/home/felix021/test/
$ fio write-test.fio
random-read: (g=0): rw=write, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
Jobs: 1 (f=1): [W] [-.-% done] [0K/409.3M /s] [0 /102K iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=10816
write: io=1024.0MB, bw=419934KB/s, iops=104983 , runt= 2497msec
clat (usec): min=0 , max=10136 , avg= 7.71, stdev=123.62
lat (usec): min=0 , max=10136 , avg= 7.98, stdev=123.64
bw (KB/s) : min=177498, max=650096, per=110.68%, avg=464776.50, stdev=202324.17
cpu : usr=14.74%, sys=57.69%, ctx=199, majf=0, minf=27
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=0/262144/0, short=0/0/0
lat (usec): 2=0.08%, 4=36.39%, 10=58.08%, 20=4.91%, 50=0.38%
lat (usec): 100=0.07%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.04%, 20=0.01%
Run status group 0 (all jobs):
WRITE: io=1024.0MB, aggrb=419934KB/s, minb=430012KB/s, maxb=430012KB/s, mint=2497msec, maxt=2497msec
Disk stats (read/write):
vdb: ios=0/1382, merge=0/11, ticks=0/219176, in_queue=246612, util=77.43%
[random-read]
rw=write
size=1g
directory=/home/felix021/test/
$ fio write-test.fio
random-read: (g=0): rw=write, bs=4K-4K/4K-4K, ioengine=sync, iodepth=1
fio 1.59
Starting 1 process
Jobs: 1 (f=1): [W] [-.-% done] [0K/409.3M /s] [0 /102K iops] [eta 00m:00s]
random-read: (groupid=0, jobs=1): err= 0: pid=10816
write: io=1024.0MB, bw=419934KB/s, iops=104983 , runt= 2497msec
clat (usec): min=0 , max=10136 , avg= 7.71, stdev=123.62
lat (usec): min=0 , max=10136 , avg= 7.98, stdev=123.64
bw (KB/s) : min=177498, max=650096, per=110.68%, avg=464776.50, stdev=202324.17
cpu : usr=14.74%, sys=57.69%, ctx=199, majf=0, minf=27
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued r/w/d: total=0/262144/0, short=0/0/0
lat (usec): 2=0.08%, 4=36.39%, 10=58.08%, 20=4.91%, 50=0.38%
lat (usec): 100=0.07%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%
lat (msec): 2=0.01%, 4=0.01%, 10=0.04%, 20=0.01%
Run status group 0 (all jobs):
WRITE: io=1024.0MB, aggrb=419934KB/s, minb=430012KB/s, maxb=430012KB/s, mint=2497msec, maxt=2497msec
Disk stats (read/write):
vdb: ios=0/1382, merge=0/11, ticks=0/219176, in_queue=246612, util=77.43%
Apr
25
1. 虽然都用 -lpthread 来链接到 libpthread.so ,但是实际上 pthread 是POSIX规范规定的接口,不是某一个库的名字。不同的类Unix系统在底层对pthread的实现不一样。
2. 在Linux的实现里,每个pthread线程都对应一个LWP(light weight process);而LWP是由内核线程支持的,由内核统一调度,所以每个pthread线程都有对应task_struct,以及对应的tid(不是pthread_self()返回的那货,而是类似于pid),所以效率就不会太高(因为切换什么的都要回到内核里,而syscall的效率……),而且对应地,还要消耗内核线程的栈空间等资源,所以效率不会很高。
3. man gettid可以看到这个syscall是在 sys/types.h 里,但是实际上在我的ubuntu 12.04, kernel 3.2.0上面没有,需要这样:
不加上的话,结果就是 error: ‘gettid’ was not declared in this scope
4. 每个线程都有单独的cpu_affinity,通过 pthread_setaffinity_np, pthread_getaffinity_np 来读写。
5. Linux下,在 /proc/[PID]/task 下面包含了进程的所有线程的相关信息,每个线程一个目录,目录名就是线程的ID;每个线程的相关信息与进程类似,:
5. 每个线程可以被调度到不同CPU上面,类似于进程的/proc/PID/stat文件,线程当前运行的CPU ID保存在对应目录内的stat文件中第39个字段:
6. 可以用ps的 L 和 F 参数列出所有的LWP:
felix021@xxx:~/code$ ps -FL
UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD
fengmin 7792 7791 7792 0 1 16561 1676 0 16:02 pts/3 00:00:00 -bash
fengmin 8660 7792 8660 0 4 11111 1004 1 17:04 pts/3 00:00:00 ./ttt
fengmin 8660 7792 8662 99 4 11111 1004 1 17:04 pts/3 00:05:05 ./ttt
fengmin 8660 7792 8663 99 4 11111 1004 15 17:04 pts/3 00:05:05 ./ttt
fengmin 8660 7792 8664 99 4 11111 1004 14 17:04 pts/3 00:05:05 ./ttt
fengmin 8692 7792 8692 0 1 16411 996 2 17:09 pts/3 00:00:00 ps -FL
其中LWP列就是LWP的id,PSR是processor,也就是CPU ID。
p.s. 另外有个GNU PTH,这个是 n:1 的,纯用户空间完成调度的线程库,POSIX兼容。
2. 在Linux的实现里,每个pthread线程都对应一个LWP(light weight process);而LWP是由内核线程支持的,由内核统一调度,所以每个pthread线程都有对应task_struct,以及对应的tid(不是pthread_self()返回的那货,而是类似于pid),所以效率就不会太高(因为切换什么的都要回到内核里,而syscall的效率……),而且对应地,还要消耗内核线程的栈空间等资源,所以效率不会很高。
3. man gettid可以看到这个syscall是在 sys/types.h 里,但是实际上在我的ubuntu 12.04, kernel 3.2.0上面没有,需要这样:
#include <sys/syscall.h>
#define gettid() syscall(__NR_gettid)
#define gettid() syscall(__NR_gettid)
不加上的话,结果就是 error: ‘gettid’ was not declared in this scope
4. 每个线程都有单独的cpu_affinity,通过 pthread_setaffinity_np, pthread_getaffinity_np 来读写。
5. Linux下,在 /proc/[PID]/task 下面包含了进程的所有线程的相关信息,每个线程一个目录,目录名就是线程的ID;每个线程的相关信息与进程类似,:
引用
felix021@xxx:/proc/8660$ ls task/
8660 8662 8663 8664
felix021@xxx:/proc/8660:/proc/8660$ ls task/8662
attr cmdline cwd exe fdinfo limits maps mounts oom_score schedstat stat status
auxv cpuset environ fd io loginuid mem oom_adj root smaps statm wchan
8660 8662 8663 8664
felix021@xxx:/proc/8660:/proc/8660$ ls task/8662
attr cmdline cwd exe fdinfo limits maps mounts oom_score schedstat stat status
auxv cpuset environ fd io loginuid mem oom_adj root smaps statm wchan
5. 每个线程可以被调度到不同CPU上面,类似于进程的/proc/PID/stat文件,线程当前运行的CPU ID保存在对应目录内的stat文件中第39个字段:
引用
felix021@xxx/proc/8660$ for i in /proc/8660/task/*; do LWP=`basename $i`; PSR=`awk '{print $39}' $i/stat`; echo $LWP, $PSR; done
8660, 1
8662, 1
8663, 15
8664, 14
8660, 1
8662, 1
8663, 15
8664, 14
6. 可以用ps的 L 和 F 参数列出所有的LWP:
引用
felix021@xxx:~/code$ ps -FL
UID PID PPID LWP C NLWP SZ RSS PSR STIME TTY TIME CMD
fengmin 7792 7791 7792 0 1 16561 1676 0 16:02 pts/3 00:00:00 -bash
fengmin 8660 7792 8660 0 4 11111 1004 1 17:04 pts/3 00:00:00 ./ttt
fengmin 8660 7792 8662 99 4 11111 1004 1 17:04 pts/3 00:05:05 ./ttt
fengmin 8660 7792 8663 99 4 11111 1004 15 17:04 pts/3 00:05:05 ./ttt
fengmin 8660 7792 8664 99 4 11111 1004 14 17:04 pts/3 00:05:05 ./ttt
fengmin 8692 7792 8692 0 1 16411 996 2 17:09 pts/3 00:00:00 ps -FL
其中LWP列就是LWP的id,PSR是processor,也就是CPU ID。
p.s. 另外有个GNU PTH,这个是 n:1 的,纯用户空间完成调度的线程库,POSIX兼容。
Apr
16
今天看到80386+里 BSF/BSR 这对指令貌似挺有意思,Bit Scan Forward/Reverse,它们的作用是正向/逆向扫描一个WORD(16bit)/DWORD(32bit),找出第一个等于1的bit编号。比如对于BX=0x1010,执行 BSF CX, BX 得到的CX=4,而 BSR CX, BX 得到的CX=12。
咋一看是个神器啊。《编程之美》什么的,不是还有一道面试题说的就是怎样快速求出一个整数中bit=1的数量么。这货加上个while循环和移位,秒杀。最新版的Intel指令手册并没有明确说它需要多少个时钟周期,不过这里的数据指出,在80486+,BSF需要6~43个时钟周期才能完成(BSR则需要6~104个clocks),也就是说,它似乎并没有被特别优化,而是使用了CPU内的微码来完成循环,所以不要指望能带来性能上的BONUS,详情可参见这篇:求整数中比特为1的二进制位数。
这篇文章里面给出的用上BSF/BSR的代码是:
想试试这段代码,不过蛋疼的是这是VS的汇编语法,GCC不能识别,于是终于下了决心翻出GCC-Inline-Assembly-HOWTO,看了下,其实也不是很复杂,简单改了下,变成这样:
跑了一下,果然效率不行,跟最差的直接循环在同一个量级。
仔细看了下代码,发现这里用的是BSR,而且还用上了n和count两个变量,感觉不太爽,于是完全改成汇编,写成这样:
结果。。。基本没变。嗯,所以就这样吧。。。
咋一看是个神器啊。《编程之美》什么的,不是还有一道面试题说的就是怎样快速求出一个整数中bit=1的数量么。这货加上个while循环和移位,秒杀。最新版的Intel指令手册并没有明确说它需要多少个时钟周期,不过这里的数据指出,在80486+,BSF需要6~43个时钟周期才能完成(BSR则需要6~104个clocks),也就是说,它似乎并没有被特别优化,而是使用了CPU内的微码来完成循环,所以不要指望能带来性能上的BONUS,详情可参见这篇:求整数中比特为1的二进制位数。
这篇文章里面给出的用上BSF/BSR的代码是:
int f4(unsigned int num) {
int count = 0;
while(num) {
int n;
__asm {
bsr eax, num
mov n, eax
}
++count;
num ^= (1 << n);
}
return count;
}
int count = 0;
while(num) {
int n;
__asm {
bsr eax, num
mov n, eax
}
++count;
num ^= (1 << n);
}
return count;
}
想试试这段代码,不过蛋疼的是这是VS的汇编语法,GCC不能识别,于是终于下了决心翻出GCC-Inline-Assembly-HOWTO,看了下,其实也不是很复杂,简单改了下,变成这样:
int f4(unsigned int num) {
int count = 0;
while(num) {
int n;
__asm__ (
"bsr %1, %%eax\n\t"
"movl %%eax, %0\n\t"
: "=r" (n)
: "r" (num)
: "%eax"
);
++count;
num ^= (1 << n);
}
return count;
}
int count = 0;
while(num) {
int n;
__asm__ (
"bsr %1, %%eax\n\t"
"movl %%eax, %0\n\t"
: "=r" (n)
: "r" (num)
: "%eax"
);
++count;
num ^= (1 << n);
}
return count;
}
跑了一下,果然效率不行,跟最差的直接循环在同一个量级。
仔细看了下代码,发现这里用的是BSR,而且还用上了n和count两个变量,感觉不太爽,于是完全改成汇编,写成这样:
int f4(unsigned int num) { //注:x86下一般都是用EAX来存函数的返回值
asm (
"movl $0, %%eax\n\t" //这里是eax存的就是count
"jmp f4_cmp\n"
"f4_loop:\n\t"
"bsf %0, %%ecx\n\t" //ecx=bsf(num)
"incb %%cl\n\t" //cl += 1
"shrl %%cl, %0\n\t" //num >>= cl; shr貌似只接受 cl 和立即数?
"incl %%eax\n" //count++
"f4_cmp:\n\t"
"cmp $0, %0\n\t"
"jnz f4_loop\n\t"
:
: "r"(num)
: "%eax", "%ecx"
);
}
asm (
"movl $0, %%eax\n\t" //这里是eax存的就是count
"jmp f4_cmp\n"
"f4_loop:\n\t"
"bsf %0, %%ecx\n\t" //ecx=bsf(num)
"incb %%cl\n\t" //cl += 1
"shrl %%cl, %0\n\t" //num >>= cl; shr貌似只接受 cl 和立即数?
"incl %%eax\n" //count++
"f4_cmp:\n\t"
"cmp $0, %0\n\t"
"jnz f4_loop\n\t"
:
: "r"(num)
: "%eax", "%ecx"
);
}
结果。。。基本没变。嗯,所以就这样吧。。。
Mar
24
原文: Reed–Solomon codes for coders
参考: AN2407.pdf
WIKI: 里德-所罗门码
实现:Pypi ReedSolo
#译注:最近看到了RS码,发现还挺有意思的,找了一些资料学习了下,发现对于程序员来说,从这篇看起会比较容易。看完以后想着翻译一下试试,看看自己到底看懂了多少,于是就有了这篇。本文有部分错误,以及一些排版不对的地方,有兴趣的还是看原文更好:)
为程序员写的Reed-Solomon码解释
Reed-Solomon纠错码(以下简称RS码)广泛用于数据存储(如CD)和传输应用中。然而,在这些应用中,码字是藏在了电子设备里,所以无法一窥它们的模样以及它们是如何生效的。有些复杂的条形码设计也采用了RS码,能够暴露出所有的细节,对于想要获得这种技术如何生效的第一手技术的爱好者,这是一种很有趣的方式。
在这篇文章里,我是试图从程序员的视角(而不是数学家的视角)来介绍RS码的基本原理。我会用以当下流行的QR码作为例子来介绍。我选择了Python(主要是因为写出来的代码看起来整洁美观),但是我也会介绍一些不那么显而易见的Python特性,以便那些不熟悉Python的人也能看懂。里头涉及到的数学知识对读者有一定要求,并且一般是大学才教授的,但是应当能让对高中代数掌握较好的人看懂。
内容:
1 QR码结构
1.1 掩码
1.2 格式信息
1.3 数据
1.4 解码
2 BCH码
2.1 BCH错误检测
2.2 BCH纠错
3 有限域理论
3.1 乘法
3.2 基于对数的乘法
3.3 除法
3.4 多项式
4 RS码
4.1 RS生成多项式
4.2 RS编码
4.3 伴随式(Syndrome)计算
4.4 消除(erasure)纠正
4.5 错误(error)纠正
4.6 消除和错误纠正
参考: AN2407.pdf
WIKI: 里德-所罗门码
实现:Pypi ReedSolo
#译注:最近看到了RS码,发现还挺有意思的,找了一些资料学习了下,发现对于程序员来说,从这篇看起会比较容易。看完以后想着翻译一下试试,看看自己到底看懂了多少,于是就有了这篇。本文有部分错误,以及一些排版不对的地方,有兴趣的还是看原文更好:)
为程序员写的Reed-Solomon码解释
Reed-Solomon纠错码(以下简称RS码)广泛用于数据存储(如CD)和传输应用中。然而,在这些应用中,码字是藏在了电子设备里,所以无法一窥它们的模样以及它们是如何生效的。有些复杂的条形码设计也采用了RS码,能够暴露出所有的细节,对于想要获得这种技术如何生效的第一手技术的爱好者,这是一种很有趣的方式。
在这篇文章里,我是试图从程序员的视角(而不是数学家的视角)来介绍RS码的基本原理。我会用以当下流行的QR码作为例子来介绍。我选择了Python(主要是因为写出来的代码看起来整洁美观),但是我也会介绍一些不那么显而易见的Python特性,以便那些不熟悉Python的人也能看懂。里头涉及到的数学知识对读者有一定要求,并且一般是大学才教授的,但是应当能让对高中代数掌握较好的人看懂。
内容:
1 QR码结构
1.1 掩码
1.2 格式信息
1.3 数据
1.4 解码
2 BCH码
2.1 BCH错误检测
2.2 BCH纠错
3 有限域理论
3.1 乘法
3.2 基于对数的乘法
3.3 除法
3.4 多项式
4 RS码
4.1 RS生成多项式
4.2 RS编码
4.3 伴随式(Syndrome)计算
4.4 消除(erasure)纠正
4.5 错误(error)纠正
4.6 消除和错误纠正
Mar
23
本来这篇应该很早就写的,一直偷懒。今天简单记录一下吧。
其实很早就想买raspberry pi,但是代购的话比原价贵太多,不了了之。后来看到mk802,说是Arm Cortex A8 1GHz + 1GB Ram,性能远超树莓派,而且可以刷原生Linux(自带的是安卓),一冲动就买了。买回来才发现,mk802只有HDMI输出,用 hdmi 转 dvi 线连 dvi 显示器不行,所以刚买回来的时候蛋疼了两天。
首先是为内置的android配置wifi。幸亏默认是打开了USB调试的,连上PC,用类似腾讯手机管家这样的软件可以看到桌面截图,如果开启连续截图的话,就可以像幻灯片一样“远程桌面”。而mk802有一个标准usb host和一个mini usb otg,因此可以直接连接鼠标和键盘。主要问题是慢,相当慢。有耐心的话还是可以设置好的,甚至我把usb摄像头连上去,可以通过android qq跟电脑视频。
其次是刷Linux。这个才是重点——如果不是它可以刷原生Linux的话我就不会买了。从MiniAnd的这个帖子下载到了ubuntu的镜像包(直接dd写到tf卡),不过问题是Linux下面默认没办法看到桌面了(没有显示器,没有网络),所以只能通过不断修改配置文件的方式来尝试让它一启动就自动连接wifi。蛋疼了好久,不过还好最后问题解决了,而且解决办法也很简单,没兴趣看基本思路的同学可以直接跳到第3步。
基本思路是:
1. 挂载tf卡(拆下来在linux上挂载,或者也可以直接在mk802的android上挂载,通过adb shell连上去即可),修改 rc.local 或其他配置,让它在启动的时候自动执行一些命令,例如 ifconfig -a 和 iwconfig 、 iwscan 等。
2. 启动mk802,等待一段时间,让它把命令的输出并重定向到某个文件,然后关掉它,再次挂载tf,读取那些信息。由此可知它的网卡名字是 wlan0 ,并且可以搜到家里的wifi。
3. 挂载tf卡,修改 /etc/network/interfaces ,加入以下这一段配置(#号和它后面的就别加了),重启后它就自动连上wifi了:
后记:某次用一个5000mah的移动电源测试大约坚持了13个小时,推算功率大约是1.5w,后来它就一直开机,作为一个小vps用了。。。
后记@2014.10.12
//from https://www.miniand.com/forums/forums/2/topics/82?page=9
其实很早就想买raspberry pi,但是代购的话比原价贵太多,不了了之。后来看到mk802,说是Arm Cortex A8 1GHz + 1GB Ram,性能远超树莓派,而且可以刷原生Linux(自带的是安卓),一冲动就买了。买回来才发现,mk802只有HDMI输出,用 hdmi 转 dvi 线连 dvi 显示器不行,所以刚买回来的时候蛋疼了两天。
首先是为内置的android配置wifi。幸亏默认是打开了USB调试的,连上PC,用类似腾讯手机管家这样的软件可以看到桌面截图,如果开启连续截图的话,就可以像幻灯片一样“远程桌面”。而mk802有一个标准usb host和一个mini usb otg,因此可以直接连接鼠标和键盘。主要问题是慢,相当慢。有耐心的话还是可以设置好的,甚至我把usb摄像头连上去,可以通过android qq跟电脑视频。
其次是刷Linux。这个才是重点——如果不是它可以刷原生Linux的话我就不会买了。从MiniAnd的这个帖子下载到了ubuntu的镜像包(直接dd写到tf卡),不过问题是Linux下面默认没办法看到桌面了(没有显示器,没有网络),所以只能通过不断修改配置文件的方式来尝试让它一启动就自动连接wifi。蛋疼了好久,不过还好最后问题解决了,而且解决办法也很简单,没兴趣看基本思路的同学可以直接跳到第3步。
基本思路是:
1. 挂载tf卡(拆下来在linux上挂载,或者也可以直接在mk802的android上挂载,通过adb shell连上去即可),修改 rc.local 或其他配置,让它在启动的时候自动执行一些命令,例如 ifconfig -a 和 iwconfig 、 iwscan 等。
2. 启动mk802,等待一段时间,让它把命令的输出并重定向到某个文件,然后关掉它,再次挂载tf,读取那些信息。由此可知它的网卡名字是 wlan0 ,并且可以搜到家里的wifi。
3. 挂载tf卡,修改 /etc/network/interfaces ,加入以下这一段配置(#号和它后面的就别加了),重启后它就自动连上wifi了:
引用
auto wlan0
iface wlan0 inet static
address 192.168.1.11
gateway 192.168.1.1
netmask 255.255.255.0
dns-nameservers 192.168.1.1
wpa-ssid OpenWrt_2E8B84 #这里是WIFI的SSID
wpa-psk password #这里是WIFI的密码
wpa-key-mgmt WPA-PSK
wpa-pairwise TKIP CCMP
wpa-group TKIP CCMP
wpa-proto WPA RSN
wpa-ap-scan 1
wpa-scan-ssid 1
iface wlan0 inet static
address 192.168.1.11
gateway 192.168.1.1
netmask 255.255.255.0
dns-nameservers 192.168.1.1
wpa-ssid OpenWrt_2E8B84 #这里是WIFI的SSID
wpa-psk password #这里是WIFI的密码
wpa-key-mgmt WPA-PSK
wpa-pairwise TKIP CCMP
wpa-group TKIP CCMP
wpa-proto WPA RSN
wpa-ap-scan 1
wpa-scan-ssid 1
后记:某次用一个5000mah的移动电源测试大约坚持了13个小时,推算功率大约是1.5w,后来它就一直开机,作为一个小vps用了。。。
后记@2014.10.12
引用
As root, create a file /etc/modprobe.d/8192cu.conf with the following contents:
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0
This prevents the power down/up cycles of the 8192 wifi chip.
options 8192cu rtw_power_mgnt=0 rtw_enusbss=0
This prevents the power down/up cycles of the 8192 wifi chip.
//from https://www.miniand.com/forums/forums/2/topics/82?page=9
Mar
23
#Update@3.23 23:05 早上9点之前密码重置功能被Apple暂停了,下午根据CNBETA的消息漏洞已经修复。
今天一个朋友的苹果帐号密码被修改,iMac、iPad、iPhone上的所有资料都被抹除,iMac被锁定无法登陆,几百GB的资料瞬间化为乌有,怀疑是同行恶意行为。悲剧详情可到v2ex的这个帖子凭吊。
根据提示这个帖子描述漏洞详情的两个连接 国外版 国内版 里提到的方法,我用自己的apple id和新注册的apple id验证,的确存在。
重置密码过程异常简单(使用chrome):
1. 登录https://iforgot.apple.com/iForgot/iForgot.html,填写指定的apple id,点击下一步
2. 选择验证方法—— 回答安全提示问题,点击下一步
3. 填写apple id注册时填写的出生日期,先不提交
4. 打开开发者工具,在elements处搜索"security"字样(某个hidden的input的value),改成null
5. 提交,进入密码重置页面,输入新密码,重置完成。
因此强烈建议立即修改自己apple id的生日
修改流程:
1. 打开 https://appleid.apple.com ,登陆
2. 点击左边的“帐户和密码安全”
3. 填写安全提示问题的答案,并点击继续
4. 在新页面里修改生日。
应该朋友要求已将操作视频录像,有兴趣的可以在 优酷 观看,或者从 百度网盘、 微云 下载,瞧瞧看看苹果的服务有多么不堪。
今天一个朋友的苹果帐号密码被修改,iMac、iPad、iPhone上的所有资料都被抹除,iMac被锁定无法登陆,几百GB的资料瞬间化为乌有,怀疑是同行恶意行为。悲剧详情可到v2ex的这个帖子凭吊。
根据提示这个帖子描述漏洞详情的两个连接 国外版 国内版 里提到的方法,我用自己的apple id和新注册的apple id验证,的确存在。
重置密码过程异常简单(使用chrome):
1. 登录https://iforgot.apple.com/iForgot/iForgot.html,填写指定的apple id,点击下一步
2. 选择验证方法—— 回答安全提示问题,点击下一步
3. 填写apple id注册时填写的出生日期,先不提交
4. 打开开发者工具,在elements处搜索"security"字样(某个hidden的input的value),改成null
5. 提交,进入密码重置页面,输入新密码,重置完成。
因此强烈建议立即修改自己apple id的生日
修改流程:
1. 打开 https://appleid.apple.com ,登陆
2. 点击左边的“帐户和密码安全”
3. 填写安全提示问题的答案,并点击继续
4. 在新页面里修改生日。
应该朋友要求已将操作视频录像,有兴趣的可以在 优酷 观看,或者从 百度网盘、 微云 下载,瞧瞧看看苹果的服务有多么不堪。
Mar
21
After wasting over 45 minutes on moving database out of the default "/var/lib/mysql" on Ubuntu, I think this crazy problem should be written down, in case someone get confused by the same problem again.
I thought this problem to be very simple: go to /etc/mysql/, edit my.cnf, change the "datadir = /var/lib/mysql" to a new place, say, /home/mysql, and run "service mysql restart". But mysqld just refused to start, it says something like this:
I'm very sure I've done chmod/chgrp to "/home/mysql", so it won't be file permission problem. It occurred to me that the original database 'mysql' may contain some path information, since it's a newly installation, so I backed up the mysql directory, tried to run "mysql_install_db --user=mysql --datadir=/home/mysql", and failed again:
and two more lines were added to the error.log:
That was weird. I used bash -x to run mysql_install_db again (it's a bash script) and found out that It started mysqld with some certain parameters which printed the Warning message shown above. So the problem went back to mysqld. A forum thread somewhere also noticed the problem but didn't come up with a solution.
With no choice, I went through the manual of mysql_install_db, and fortunately found a comment at the end of the page:
As the 'usr.sbin.mysql' requests, I added two lines to the end of "/etc/apparmor.d/local/user.sbin.mysql" and restarted apparmor(/etc/init.d/apparmor restart), thus fixed the problem.
I thought this problem to be very simple: go to /etc/mysql/, edit my.cnf, change the "datadir = /var/lib/mysql" to a new place, say, /home/mysql, and run "service mysql restart". But mysqld just refused to start, it says something like this:
引用
/usr/sbin/mysqld: Can't find file: './mysql/plugin.frm' (errno: 13)
130321 22:48:26 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
130321 22:48:26 [Note] Server hostname (bind-address): '127.0.0.1'; port: 3306
130321 22:48:26 [Note] - '127.0.0.1' resolves to '127.0.0.1';
130321 22:48:26 [Note] Server socket created on IP: '127.0.0.1'.
130321 22:48:26 [ERROR] /usr/sbin/mysqld: Can't find file: './mysql/host.frm' (errno: 13)
130321 22:48:26 [ERROR] Fatal error: Can't open and lock privilege tables: Can't find file: './mysql/host.frm' (errno: 13)
130321 22:48:26 [ERROR] Can't open the mysql.plugin table. Please run mysql_upgrade to create it.
130321 22:48:26 [Note] Server hostname (bind-address): '127.0.0.1'; port: 3306
130321 22:48:26 [Note] - '127.0.0.1' resolves to '127.0.0.1';
130321 22:48:26 [Note] Server socket created on IP: '127.0.0.1'.
130321 22:48:26 [ERROR] /usr/sbin/mysqld: Can't find file: './mysql/host.frm' (errno: 13)
130321 22:48:26 [ERROR] Fatal error: Can't open and lock privilege tables: Can't find file: './mysql/host.frm' (errno: 13)
I'm very sure I've done chmod/chgrp to "/home/mysql", so it won't be file permission problem. It occurred to me that the original database 'mysql' may contain some path information, since it's a newly installation, so I backed up the mysql directory, tried to run "mysql_install_db --user=mysql --datadir=/home/mysql", and failed again:
引用
$ mysql_install_db --user=mysql --datadir=/home/mysql/
Installing MySQL system tables...
130321 23:18:17 [Warning] Can't create test file /home/mysql/localhost.lower-test
130321 23:18:17 [Warning] Can't create test file /home/mysql/localhost.lower-test
Installation of system tables failed! Examine the logs in/home/mysql/ for more information.
Installing MySQL system tables...
130321 23:18:17 [Warning] Can't create test file /home/mysql/localhost.lower-test
130321 23:18:17 [Warning] Can't create test file /home/mysql/localhost.lower-test
Installation of system tables failed! Examine the logs in/home/mysql/ for more information.
and two more lines were added to the error.log:
引用
ERROR: 1005 Can't create table 'db' (errno: 13)
130321 23:06:48 [ERROR] Aborting
130321 23:06:48 [ERROR] Aborting
That was weird. I used bash -x to run mysql_install_db again (it's a bash script) and found out that It started mysqld with some certain parameters which printed the Warning message shown above. So the problem went back to mysqld. A forum thread somewhere also noticed the problem but didn't come up with a solution.
With no choice, I went through the manual of mysql_install_db, and fortunately found a comment at the end of the page:
引用
Ubuntu 9.10
Moving the database from /var/lib/mysql to /data/databases/mysql
You'll get errors when running mysql_install_db until you go into /etc/apparmor.d, update the usr.sbin.mysql file, and run /etc/init.d/apparmor restart
You may also get an error when running /etc/init.d/mysql start:
Access denied for user debian-sys-maint at localhost
Check /etc/mysql/debian.cnf for the account information.
You'll need to run mysql, add the grant tables, and then restart mysql.
Moving the database from /var/lib/mysql to /data/databases/mysql
You'll get errors when running mysql_install_db until you go into /etc/apparmor.d, update the usr.sbin.mysql file, and run /etc/init.d/apparmor restart
You may also get an error when running /etc/init.d/mysql start:
Access denied for user debian-sys-maint at localhost
Check /etc/mysql/debian.cnf for the account information.
You'll need to run mysql, add the grant tables, and then restart mysql.
As the 'usr.sbin.mysql' requests, I added two lines to the end of "/etc/apparmor.d/local/user.sbin.mysql" and restarted apparmor(/etc/init.d/apparmor restart), thus fixed the problem.
引用
/home/mysql/ r,
/home/mysql/** rwk,
/home/mysql/** rwk,
Mar
18
在RSA算法里头经常要用到“求x的n次方模m”这样的过程,通常使用O(log(n))的模重复平方算法来实现,提高效率。
其实这是大二学的《信息安全数学基础》里面的内容,那时为了考试需要(手算+写出很罗嗦的过程),还专门写了代码放在Blog空间里考试的时候用—……
同样O(log(n))的递归算法其实很容易理解:
但是SICP要求写一个迭代版的。印象中我是记得可以把 n 写成二进制(比如n=13, 1101),然后一位一位地推。
试推了一下从高位到低位,倒是挺简单的,记B[i]为第 i 位的值,通过A[i] = A[i+1]^2 * x^B[i] 从高到低计算出A[0],就得到结果了。但是问题是,为了从高到低计算,又得一次递归,似乎不能满足要求。
于是只好反过来,从低位往高位推。这个过程其实也挺简单的,举例来说:
当n=13,即二进制的 1101 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0时,最终结果
ans = x^n % m
= x^(1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0) % m
= [x^(1 * 2^3)] * [x^(1 * 2^2)] * [(x ^ (0 * 2^1)] * [x ^ (1 * 2^0)] % m
也就是说,从低到高,在第 i 位的时候,将 x^(Bit[i] * 2^i) % m 乘到结果中即可。这里可以稍微变换一下:仅当Bit[i] == 1的时候,将x^(2^i) % m乘进去即可。所以这里可以用一个辅助的变量 b 来保存 x^(2^i) % m,在每次迭代的过程中 b = b^2 % m 。
于是实现就容易了:
//网上搜了下模重复平方算法,居然没有靠谱的算法解释,看来可能还是这个算法太简单了吧。。。
其实这是大二学的《信息安全数学基础》里面的内容,那时为了考试需要(手算+写出很罗嗦的过程),还专门写了代码放在Blog空间里考试的时候用—……
同样O(log(n))的递归算法其实很容易理解:
/* C */
int square(int x) { return x * x; } /* 这里可不能用宏哟 */
int fast_mod(int x, int n, int m)
{
if (n == 0)
return 1;
else if (n % 2 == 0)
return square(fast_mod(x, n / 2, m)) % m;
else
return x * fast_mod(x, n - 1, m) % m;
}
#Python
fast_mod = lambda x, n, m: 1 if n == 0 else fast_mod(x, n / 2, m) ** 2 % m if n % 2 == 0 else x * fast_mod(x, n - 1, m) % m
;Scheme
(define (even? n) (= (remainder n 2) 0))
(define (mod-fast x n m)
(define (square x) (* x x))
(cond ((= n 0) 1)
((even? n) (remainder (square (mod-fast x (/ n 2) m)) m))
(else (remainder (* x (mod-fast x (- n 1) m)) m))))
(mod-fast 79 24 33)
;16
int square(int x) { return x * x; } /* 这里可不能用宏哟 */
int fast_mod(int x, int n, int m)
{
if (n == 0)
return 1;
else if (n % 2 == 0)
return square(fast_mod(x, n / 2, m)) % m;
else
return x * fast_mod(x, n - 1, m) % m;
}
#Python
fast_mod = lambda x, n, m: 1 if n == 0 else fast_mod(x, n / 2, m) ** 2 % m if n % 2 == 0 else x * fast_mod(x, n - 1, m) % m
;Scheme
(define (even? n) (= (remainder n 2) 0))
(define (mod-fast x n m)
(define (square x) (* x x))
(cond ((= n 0) 1)
((even? n) (remainder (square (mod-fast x (/ n 2) m)) m))
(else (remainder (* x (mod-fast x (- n 1) m)) m))))
(mod-fast 79 24 33)
;16
但是SICP要求写一个迭代版的。印象中我是记得可以把 n 写成二进制(比如n=13, 1101),然后一位一位地推。
试推了一下从高位到低位,倒是挺简单的,记B[i]为第 i 位的值,通过A[i] = A[i+1]^2 * x^B[i] 从高到低计算出A[0],就得到结果了。但是问题是,为了从高到低计算,又得一次递归,似乎不能满足要求。
于是只好反过来,从低位往高位推。这个过程其实也挺简单的,举例来说:
当n=13,即二进制的 1101 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0时,最终结果
ans = x^n % m
= x^(1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0) % m
= [x^(1 * 2^3)] * [x^(1 * 2^2)] * [(x ^ (0 * 2^1)] * [x ^ (1 * 2^0)] % m
也就是说,从低到高,在第 i 位的时候,将 x^(Bit[i] * 2^i) % m 乘到结果中即可。这里可以稍微变换一下:仅当Bit[i] == 1的时候,将x^(2^i) % m乘进去即可。所以这里可以用一个辅助的变量 b 来保存 x^(2^i) % m,在每次迭代的过程中 b = b^2 % m 。
于是实现就容易了:
/* C */
int fast_mod_iter(int x, int n, int m)
{
int a = 1, b = x; //i=0的时候b = x^(2^0) = x
while (n)
{
if (n % 2 == 1)
a = a * b % m;
b = b * b % m;
n /= 2;
}
return a;
}
#Python
def fast_mod(x, n, m):
a = 1
b = x
while True:
if n == 0:
return a
if n % 2 == 1:
a = a * b % m
b = b * b % m
n /= 2
;Scheme
(define (even? n) (= (remainder n 2) 0))
(define (mod-fast-iter x n m)
(define (iter a b n)
(cond ((= n 0) a)
((even? n)
(iter a (remainder (* b b) m) (/ n 2)))
(else
(iter (remainder (* a b) m) (* b b) (/ (- n 1) 2)))))
(iter 1 x n))
(mod-fast-iter 79 24 33)
;16
int fast_mod_iter(int x, int n, int m)
{
int a = 1, b = x; //i=0的时候b = x^(2^0) = x
while (n)
{
if (n % 2 == 1)
a = a * b % m;
b = b * b % m;
n /= 2;
}
return a;
}
#Python
def fast_mod(x, n, m):
a = 1
b = x
while True:
if n == 0:
return a
if n % 2 == 1:
a = a * b % m
b = b * b % m
n /= 2
;Scheme
(define (even? n) (= (remainder n 2) 0))
(define (mod-fast-iter x n m)
(define (iter a b n)
(cond ((= n 0) a)
((even? n)
(iter a (remainder (* b b) m) (/ n 2)))
(else
(iter (remainder (* a b) m) (* b b) (/ (- n 1) 2)))))
(iter 1 x n))
(mod-fast-iter 79 24 33)
;16
//网上搜了下模重复平方算法,居然没有靠谱的算法解释,看来可能还是这个算法太简单了吧。。。