Redis-Clojure: NoRouteToHostException

已查看 71 次
跳至第一个未读帖子

mudphone

未读,
2010年1月13日 14:48:582010/1/13
收件人 Clojure
This is a problem I'm having with the Redis-Clojure library, which is
not strictly a Clojure issue. But, I know there are a lot of folks
using it in the community, so I thought this might be a good shot for
getting help. Sorry for the cross-post.

After adding about 16328 members to a set, the stack trace shows up.
I believe it has to do with opening too many sockets on the Redis
server, rather than the total number of members in the set. Is anyone
using a connection pool with Redis-Clojure? If so, is there an
example of one somewhere? Or, am I totally off base here?

I think this error may also be causing a "Can't read correct number of
bytes" error that is thrown by Redis-Clojure itself after some point
(possibly after ports are all in use?).

The code I'm using to reproduce this exception is here:
http://gist.github.com/276511

Any suggestions appreciated.

Thanks,
Kyle

adding member # 100000
... counts down ...
adding member # 83672

Exception in thread "main" java.net.NoRouteToHostException: Can't
assign requested address (test_redis.clj:0)
at clojure.lang.Compiler.eval(Compiler.java:4617)
at clojure.lang.Compiler.load(Compiler.java:4931)
at clojure.lang.Compiler.loadFile(Compiler.java:4898)
at clojure.main$load_script__6637.invoke(main.clj:210)
at clojure.main$init_opt__6640.invoke(main.clj:215)
at clojure.main$initialize__6650.invoke(main.clj:243)
at clojure.main$null_opt__6672.invoke(main.clj:268)
at clojure.main$legacy_script__6687.invoke(main.clj:299)
at clojure.lang.Var.invoke(Var.java:359)
at clojure.main.legacy_script(main.java:32)
at clojure.lang.Script.main(Script.java:20)
Caused by: java.net.NoRouteToHostException: Can't assign requested
address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress
(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
at java.net.Socket.connect(Socket.java:525)
at java.net.Socket.connect(Socket.java:475)
at java.net.Socket.<init>(Socket.java:372)
at java.net.Socket.<init>(Socket.java:186)
at redis.internal$connect_to_server__44.invoke(internal.clj:32)
at redis.internal$with_server_STAR___49.invoke(internal.clj:41)
at user$add_random_value_to_set__588.invoke(test_redis.clj:38)
at user$create_large_set__594.invoke(test_redis.clj:45)
at user$eval__600.invoke(test_redis.clj:50)
at clojure.lang.Compiler.eval(Compiler.java:4601)
... 10 more

Timothy Pratley

未读,
2010年1月13日 16:29:412010/1/13
收件人 clo...@googlegroups.com
2010/1/14 mudphone <kyl...@gmail.com>:

> I believe it has to do with opening too many sockets on the Redis
> server, rather than the total number of members in the set.

Sounds possible. It would be worthwhile seeing if
(redis/with-server REDIS-SPEC
(dotimes [i 100000] (redis/sadd "large-set" (random-value i))))
works as expected (ie: using just one connection) to help isolate the problem.

From looking at
http://github.com/ragnard/redis-clojure/blob/master/src/redis/internal.clj
it appears that the sockets are cleaned up... so I'm thinking it is
actually more likely that the sockets are closed, but that you use
them all so fast that none are available before you request a new one
because their timeout has not expired. Sockets bind to a fixed remote
host port and a (usually) random local port. But the local ports
cannot be reused immediately (there is a timeout) unless the socket
specifically is set as reuse. If you ran out of sockets I would expect
an exception more like "no file descriptors". You could run netstat
when your program is half-way done to get a better picture.


> Any suggestions appreciated.

Consider using dotimes, or doseq instead of loop/recur
(doseq [i (range 10 0 -1)] (println i)) ;; if you want to count down
instead of up


I'm not a Redis user yet so apologies if not helpful.


Regards,
Tim.

mudphone

未读,
2010年1月14日 16:15:252010/1/14
收件人 Clojure
Timothy,

Thanks for the suggestion. Creating a million keys within the same
with-server is possible, without seeing the NoRouteToHostException.
So, hitting with-server so many times in so short a time period is
definitely a bad idea (duh).

So, I think there is a problem with how my larger program (not in the
gist) is using the redis-clojure library. I'm still seeing
intermitted problems with "Not able to read expected number or bytes"
which might be related. I'll post here if it turns out that it's
related.

Also, thanks for the dotimes/doseq suggestion. I hadn't worried about
it, since it was just a quick example. But, thanks for the tip.

Regards,
Kyle

On Jan 13, 1:29 pm, Timothy Pratley <timothyprat...@gmail.com> wrote:
> 2010/1/14 mudphone <kyle...@gmail.com>:


>
> > I believe it has to do with opening too many sockets on the Redis
> > server, rather than the total number of members in the set.
>
> Sounds possible. It would be worthwhile seeing if
> (redis/with-server REDIS-SPEC
>   (dotimes [i 100000] (redis/sadd "large-set" (random-value i))))
> works as expected (ie: using just one connection) to help isolate the problem.
>

> From looking athttp://github.com/ragnard/redis-clojure/blob/master/src/redis/interna...

回复全部
回复作者
转发
0 个新帖子