@@ -2,46 +2,58 @@ package com.redislabs.provider.redis
2
2
3
3
import java .net .URI
4
4
5
+ import org .apache .commons .pool2 .impl .GenericObjectPoolConfig
5
6
import org .apache .spark .SparkConf
6
- import redis .clients .jedis .Jedis
7
+ import redis .clients .jedis .{ JedisPool , Jedis , Protocol }
7
8
import redis .clients .util .{JedisURIHelper , SafeEncoder , JedisClusterCRC16 }
8
9
import scala .collection .JavaConversions ._
9
10
10
11
11
12
/**
12
- * RedisEndpoint represents a redis connection endpoint info: host, port, auth password and db number
13
+ * RedisEndpoint represents a redis connection endpoint info: host, port, auth password
14
+ * db number, and timeout
15
+ *
13
16
* @param host the redis host or ip
14
17
* @param port the redis port
15
18
* @param auth the authentication password
16
19
* @param dbNum database number (should be avoided in general)
17
20
*/
18
- class RedisEndpoint (val host : String , val port : Int , val auth : String = " " , val dbNum : Int = 0 )
21
+ case class RedisEndpoint (val host : String = Protocol .DEFAULT_HOST ,
22
+ val port : Int = Protocol .DEFAULT_PORT ,
23
+ val auth : String = null ,
24
+ val dbNum : Int = Protocol .DEFAULT_DATABASE ,
25
+ val timeout : Int = Protocol .DEFAULT_TIMEOUT )
19
26
extends Serializable {
20
27
28
+ @ transient private var pool : JedisPool = null
29
+
21
30
/**
22
31
* Constructor from spark config. set params with redis.host, redis.port, redis.auth and redis.db
32
+ *
23
33
* @param conf spark context config
24
34
*/
25
35
def this (conf : SparkConf ) {
26
36
this (
27
- conf.get(" redis.host" , " localhost" ),
28
- conf.get(" redis.port" , " 6379" ).toInt,
29
- conf.get(" redis.auth" , " " ),
30
- conf.get(" redis.db" , " 0" ).toInt
37
+ conf.get(" redis.host" , Protocol .DEFAULT_HOST ),
38
+ conf.getInt(" redis.port" , Protocol .DEFAULT_PORT ),
39
+ conf.get(" redis.auth" , null ),
40
+ conf.getInt(" redis.db" , Protocol .DEFAULT_DATABASE ),
41
+ conf.getInt(" redis.timeout" , Protocol .DEFAULT_TIMEOUT )
31
42
)
32
43
}
33
44
34
45
/**
35
46
* Constructor with Jedis URI
47
+ *
36
48
* @param uri connection URI in the form of redis://:$password@$host:$port/[dbnum]
37
49
*/
38
-
39
50
def this (uri : URI ) {
40
51
this (uri.getHost, uri.getPort, JedisURIHelper .getPassword(uri), JedisURIHelper .getDBIndex(uri))
41
52
}
42
53
43
54
/**
44
55
* Constructor with Jedis URI from String
56
+ *
45
57
* @param uri connection URI in the form of redis://:$password@$host:$port/[dbnum]
46
58
*/
47
59
def this (uri : String ) {
@@ -54,36 +66,32 @@ class RedisEndpoint(val host: String, val port: Int, val auth: String = "", val
54
66
*
55
67
* @return a new Jedis instance
56
68
*/
57
- def connect (): Jedis = {
58
- val client = new Jedis (this .host, this .port)
59
-
60
- // if a password was set - auth
61
- if (! Option (auth).getOrElse(" " ).isEmpty) {
62
- client.auth(auth)
69
+ def connect (): Jedis = {
70
+ if (pool == null ) {
71
+ pool = new JedisPool (new GenericObjectPoolConfig (), host, port, timeout, auth, dbNum)
63
72
}
64
-
65
- // if a db num was set, select it
66
- if (dbNum > 0 ) {
67
- client.select(dbNum)
68
- }
69
-
70
- client
73
+ pool.getResource
71
74
}
72
75
}
73
76
74
77
case class RedisNode (val endpoint : RedisEndpoint ,
75
78
val startSlot : Int ,
76
79
val endSlot : Int ,
77
80
val idx : Int ,
78
- val total : Int )
81
+ val total : Int ) {
82
+ def connect (): Jedis = {
83
+ endpoint.connect
84
+ }
85
+
86
+ }
79
87
80
88
/**
81
89
* RedisConfig holds the state of the cluster nodes, and uses consistent hashing to map
82
90
* keys to nodes
83
91
*/
84
92
class RedisConfig (val initialHost : RedisEndpoint ) extends Serializable {
85
93
86
- val currentAddr = initialHost.host
94
+ val initialAddr = initialHost.host
87
95
88
96
val hosts = getHosts(initialHost)
89
97
val nodes = getNodes(initialHost)
@@ -126,8 +134,7 @@ class RedisConfig(val initialHost: RedisEndpoint) extends Serializable {
126
134
* @return jedis who is a connection for a given key
127
135
*/
128
136
def connectionForKey (key : String ): Jedis = {
129
- val host = getHost(key).endpoint
130
- host.connect
137
+ getHost(key).connect
131
138
}
132
139
133
140
/**
@@ -194,7 +201,8 @@ class RedisConfig(val initialHost: RedisEndpoint) extends Serializable {
194
201
val nodes = master +: slaves
195
202
val range = nodes.size
196
203
(0 until range).map(i =>
197
- RedisNode (new RedisEndpoint (nodes(i)._1, nodes(i)._2, initialHost.auth, initialHost.dbNum),
204
+ RedisNode (new RedisEndpoint (nodes(i)._1, nodes(i)._2, initialHost.auth, initialHost.dbNum,
205
+ initialHost.timeout),
198
206
0 , 16383 , i, range)).toArray
199
207
}
200
208
}
@@ -205,7 +213,6 @@ class RedisConfig(val initialHost: RedisEndpoint) extends Serializable {
205
213
*/
206
214
private def getClusterNodes (initialHost : RedisEndpoint ): Array [RedisNode ] = {
207
215
val conn = initialHost.connect()
208
- val slots = conn.clusterSlots()
209
216
val res = conn.clusterSlots().flatMap {
210
217
slotInfoObj => {
211
218
val slotInfo = slotInfoObj.asInstanceOf [java.util.List [java.lang.Object ]]
@@ -224,7 +231,8 @@ class RedisConfig(val initialHost: RedisEndpoint) extends Serializable {
224
231
val node = slotInfo(i + 2 ).asInstanceOf [java.util.List [java.lang.Object ]]
225
232
val host = SafeEncoder .encode(node.get(0 ).asInstanceOf [Array [scala.Byte ]])
226
233
val port = node.get(1 ).toString.toInt
227
- RedisNode (new RedisEndpoint (host, port, initialHost.auth, initialHost.dbNum),
234
+ RedisNode (new RedisEndpoint (host, port, initialHost.auth, initialHost.dbNum,
235
+ initialHost.timeout),
228
236
sPos,
229
237
ePos,
230
238
i,
0 commit comments