您的位置:首页 > 业界新闻

一个分布式系统的偶然研究(updated)

2004-12-11 20:00 323 查看
这是一次很偶然的发现,连自己都觉得意外..............

背景:1.本宿舍楼浴室
            2.一卡通校园卡以及读卡收费器(自动感应)
            3.刷卡规则,将一卡通卡片放在读卡器正面,1秒左右自动读取1元并开始放水,每4秒计费一次,每次
               扣除1分钱。1元钱全部扣除或者再次刷卡都可将洗澡水停下。消费金额按照读卡器扣除金额为准。
研究:2张不同学生的卡片按照一定次序打卡的结果

时间:中午13点左右
         一开始没有想到这些问题,像平常一样洗澡。突然觉得同学的卡能不能停下我的水呢?我就尝试打了一下,结果计费器显示从同学的卡片上扣除了我的计费器上的金额。心里有些不安,然后用自己的卡打开龙头,奇迹出现了,我的卡显示金额还是在刚刚消费之前的金额。我估计是把刚才的消费都在同学的卡上扣除了。然后我想到了,对数据库操作产生脏数据的推断。于是,我想到了如下的策略(以脏数据问题作为指导):

         我的卡:A    我用的龙头为:L1
         同学的卡:B 同学的龙头:L2
       1.用A卡使L1流水,开始计费,假设此时卡上有20元整。开始洗澡。
       2.L1上的钱剩下0.05左右(马上就要停水并对卡片A进行计费时),用A卡打开L2,然后迅速用A关上L1。然后,迅速关上L2。按照脏数据问题,可以知道,此时的读卡器主动参与计费,等待计费结束,update数据库扣除消费。这样子,在L1上消费被当作脏数据从数据库当中被L2的更新覆盖了。也就是说,读卡器的读卡规则是,首先记录A卡的余额,然后开始计费。再次打卡将从余额中扣除读卡器上消费金额。从而L1,L2读卡时的余额应该是一样的,但是2台机器计费额是不同的,由于先后写入的次序不同造成脏数据。
       3.用A使L1流水,假设此时B当中只有1元(不足1元不能读卡,否则就可以透支了,看来设计者想到了这一点)。用B卡停止L1流水。此时,L1写回B卡中A卡数据。从而造成数据混乱,并可以作为提高卡片余额的“好方法”。与上面的想法不同,这里脏数据的读写是在L1读取并记录A的余额并在第二次打卡的时候就已经计算好余额并写回A当中作为策略的。因此,B卡当中写回的是A卡的数据。也就是说,不会产生2中的现象。但是也不能证明2中的问题可以因此解决。

结果:利用一卡通管理设备,从互联网上查询并计算金额却发现,在中午消费的过程当中整个消费金额并没有因为试验的原因而真正的减少。从消费次数来看,果真在消费过程当中卡片消费次数并不是像往常一样顺序增加,而是跳跃式的211    213    216........看来,消费确实存在一定的跳跃性,但是为什么金额不会因为脏数据理论而减少或者有目的增加呢?

在仔细的对数据库报表进行分析以后得到了一些结论,数据表内容如下:

2004/11/30 13:05:50 卡片消费  2004/11/30 13:17:55 23.00 -0.79 22.21 水控子系统  220 正常
2004/11/30 13:00:23 卡片消费  2004/11/30 13:11:12 24.02 -0.02 24.00 水控子系统  217 正常
2004/11/30 13:00:19 卡片消费  2004/11/30 13:11:08 23.60 -0.58 23.02 水控子系统  216 正常
2004/11/30 12:51:50 卡片消费  2004/11/30 13:02:45 24.62 -0.02 24.60 水控子系统  213 正常
2004/11/30 12:51:35 卡片消费  2004/11/30 13:02:30 24.85 -0.23 24.62 水控子系统  211 正常
2004/11/30 12:51:13 卡片消费  2004/11/30 13:02:09 24.00 -0.15 23.85 水控子系统  210 正常
2004/11/30 12:49:51 卡片消费  2004/11/30 13:00:47 24.01 -0.01 24.00 水控子系统  208 正常
2004/11/30 12:48:43 卡片消费  2004/11/30 12:59:40 25.06 -0.05 25.01 水控子系统  205 正常
2004/11/30 12:47:37 卡片消费  2004/11/30 12:58:35 25.19 -0.13 25.06 水控子系统  203 正常
2004/11/30 12:44:18 卡片消费  2004/11/30 12:55:18 25.48 -0.29 25.19 水控子系统  201 正常
可以看到数据的跳跃性,但是消费总额并没有变化。
但是从码的角度来讲,可以看到这个消费系统当中时间是主码,因为当时间不同消费金额会产生差别,靠这种机制完成计费以及对卡消费次序的正确纪录,避免了脏数据的读写。但是,从另一方面不太理解,如果消费次数没有区别的功能,为什么还有这项一眼就能看出问题的数据项存在呢?
就此问题,我们进一步想,如果使用时间作为主码,那么消费前后的2个时间怎么作为主码?如果1次消费从另一次消费当中,怎么办呢?比方说用A先后打开L1    L2呢?这些就不得而知了。

但是有一点可以肯定,在计费机器方面有可能存在编号问题,每一笔消费都是按照消费机器的编号区别的,但是这样子的矛盾在于如果我用B卡结束A卡的消费,数据库会怎样纪录数据呢?但无论怎么说,这个推断的说服力最大。

还有一个现象,就是如果你在中午消费,比方说去餐厅就餐。但是你的清算结果应该是在下午才能查询出来,在这中间的延时很可能是暂存在计费机器当中造成的。那么为什么在数据的update得时候没有机器编号在里面呢?如果错误的消费过后如何查询并退回错误操作的那部分钱呢?

也许这样的分布式系统当中还有很多我没有学到的策略和机制。所谓人外有人,山外有山啊!

   
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据库 互联网 报表