随便写一句,以免有跟我一样的人遇到这个问题。
驱动版本:MongoDB C# Driver 1.7.0
当在Master/Slave集群上使用Eval的时候,Eval操作只会在Master结点上运行,无论你设置的readPreference是secondaryPreferred还是secondary。理由很简单,Eval中的JS并不是在客户端(即驱动中)解释执行,而是在MongoDB中。所以当驱动收到一条Eval命令的时候并不知道具体是要干什么,所以无法判断应该把这个请求发给master还是slave去执行。为了保证执行顺利,驱动总是把这样的命令发给Master执行。这点我个人认为值得商榷。至少应该给我个机会指定使用Master还是Slave,否则所有Eval都会跑到Master上,增加了Master的压力,违背了做Master/Slave的初衷。
明白这点以后,如果在程序中发现"not master"的错误,就不会无法理解了。这是因为Eval发送到了Master上,而Master因为压力过大无法接受新的请求导致不能接受请求,因此请求可能被转发到Slave节点上,导致报了Not Master错误(一说是Master正在进行角色转换变成Slave,不过据我观察应该我说的原因可能性比较大)。这里极有可能是驱动的Bug,但还未确认。因为既然会把请求转到Slave节点上,那readPreference=secondary/secondaryPreferred配置就应该起作用。