redis.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. package redis
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "log"
  6. "runtime"
  7. "strings"
  8. "time"
  9. redigo "github.com/garyburd/redigo/redis"
  10. )
  11. var RedisPool map[string]*redigo.Pool
  12. //初始化redis 1为多个连接池,2为共用一个连接池
  13. func InitRedis(addrs string) {
  14. InitRedisBySize(addrs, 80, 10, 240)
  15. }
  16. func InitRedisBySize(addrs string, maxSize, maxIdle, timeout int) {
  17. RedisPool = map[string]*redigo.Pool{}
  18. addr := strings.Split(addrs, ",")
  19. for _, v := range addr {
  20. saddr := strings.Split(v, "=")
  21. RedisPool[saddr[0]] = &redigo.Pool{MaxActive: maxSize, MaxIdle: maxIdle,
  22. IdleTimeout: time.Duration(timeout) * time.Second, Dial: func() (redigo.Conn, error) {
  23. c, err := redigo.Dial("tcp", saddr[1])
  24. if err != nil {
  25. log.Printf("redis addr [%s] init error:[%v]", saddr[0], err)
  26. return nil, err
  27. }
  28. return c, nil
  29. }}
  30. }
  31. }
  32. //分流redis
  33. //并存入字符串缓存
  34. func PutKV(key string, obj interface{}) bool {
  35. return Put("other", key, obj, -1)
  36. }
  37. func PutCKV(code, key string, obj interface{}) bool {
  38. return Put(code, key, obj, -1)
  39. }
  40. func Put(code, key string, obj interface{}, timeout int) bool {
  41. b := false
  42. defer catch()
  43. conn := RedisPool[code].Get()
  44. defer conn.Close()
  45. var err error
  46. _obj, _err := json.Marshal(obj)
  47. if _err != nil {
  48. log.Println("redisutil-SET-序列化出错Error", _err)
  49. return b
  50. }
  51. if timeout < 1 {
  52. _, err = conn.Do("SET", key, _obj)
  53. } else {
  54. _, err = conn.Do("SET", key, _obj, "EX", timeout)
  55. }
  56. if nil != err {
  57. log.Println("redisutil-SETError-put", err)
  58. } else {
  59. b = true
  60. }
  61. return b
  62. }
  63. func BulkPut(code string, timeout int, obj ...interface{}) bool {
  64. b := false
  65. defer catch()
  66. conn := RedisPool[code].Get()
  67. defer conn.Close()
  68. var err error
  69. for _, _tmp := range obj {
  70. tmp, ok := _tmp.([]interface{})
  71. if ok && len(tmp) == 2 {
  72. key, kok := tmp[0].(string)
  73. if kok && key != "" {
  74. _obj, _err := json.Marshal(tmp[1])
  75. if _err != nil {
  76. log.Println("redisutil-SET-序列化出错Error", _err)
  77. return b
  78. }
  79. if timeout < 1 {
  80. _, err = conn.Do("SET", key, _obj)
  81. } else {
  82. _, err = conn.Do("SET", key, _obj, "EX", timeout)
  83. }
  84. }
  85. }
  86. }
  87. if nil != err {
  88. b = false
  89. log.Println("redisutil-SETError-put", err)
  90. } else {
  91. b = b && true
  92. }
  93. return b
  94. }
  95. //直接存字节流
  96. func PutBytes(code, key string, data *[]byte, timeout int) (err error) {
  97. defer catch()
  98. conn := RedisPool[code].Get()
  99. defer conn.Close()
  100. if timeout < 1 {
  101. _, err = conn.Do("SET", key, *data)
  102. } else {
  103. _, err = conn.Do("SET", key, *data, "EX", timeout)
  104. }
  105. if nil != err {
  106. log.Println("redisutil-SETError", err)
  107. }
  108. return
  109. }
  110. //设置超时时间,单位秒
  111. func SetExpire(code, key string, expire int) error {
  112. defer catch()
  113. conn := RedisPool[code].Get()
  114. defer conn.Close()
  115. _, err := conn.Do("expire", key, expire)
  116. return err
  117. }
  118. //判断一个key是否存在
  119. func Exists(code, key string) (bool, error) {
  120. defer catch()
  121. conn := RedisPool[code].Get()
  122. defer conn.Close()
  123. repl, err := conn.Do("exists", key)
  124. ret, _ := redigo.Int(repl, err)
  125. return ret == 1, err
  126. }
  127. //获取string
  128. func GetStr(code, key string) string {
  129. res := Get(code, key)
  130. str, _ := res.(string)
  131. return str
  132. }
  133. //获取int
  134. func GetInt(code, key string) int {
  135. result, _ := GetNewInt(code, key)
  136. return result
  137. }
  138. func GetNewInt(code, key string) (int, error) {
  139. var res interface{}
  140. err := GetNewInterface(code, key, &res)
  141. var result int
  142. if str, ok := res.(float64); ok {
  143. result = int(str)
  144. }
  145. return result, err
  146. }
  147. //取得字符串,支持变参,2个 (key,code),返回后自己断言
  148. func Get(code, key string) (result interface{}) {
  149. GetInterface(code, key, &result)
  150. return
  151. }
  152. func GetInterface(code, key string, result interface{}) {
  153. GetNewInterface(code, key, result)
  154. }
  155. func GetNewInterface(code, key string, result interface{}) error {
  156. defer catch()
  157. conn := RedisPool[code].Get()
  158. defer conn.Close()
  159. ret, err := conn.Do("GET", key)
  160. if nil != err {
  161. log.Println("redisutil-GetError", err)
  162. } else {
  163. var ok bool
  164. var res []byte
  165. if res, ok = ret.([]byte); ok {
  166. err = json.Unmarshal(res, result)
  167. if err != nil {
  168. log.Println("Get ERROR:", err.Error())
  169. }
  170. }
  171. }
  172. return err
  173. }
  174. //直接返回字节流
  175. func GetBytes(code, key string) (ret *[]byte, err error) {
  176. defer catch()
  177. conn := RedisPool[code].Get()
  178. defer conn.Close()
  179. var r interface{}
  180. r, err = conn.Do("GET", key)
  181. if err != nil {
  182. log.Println("redisutil-GetBytesError", err)
  183. } else {
  184. if tmp, ok := r.([]byte); ok {
  185. ret = &tmp
  186. } else {
  187. err = errors.New("redis返回数据格式不对")
  188. }
  189. }
  190. return
  191. }
  192. func GetNewBytes(code, key string) (ret *[]byte, err error) {
  193. defer catch()
  194. redisPool := RedisPool[code]
  195. if redisPool == nil {
  196. err = errors.New("redis code " + code + " is nil")
  197. log.Println("redisutil-GetNewBytesError", err)
  198. return
  199. }
  200. conn := redisPool.Get()
  201. defer conn.Close()
  202. var r interface{}
  203. r, err = conn.Do("GET", key)
  204. if err != nil {
  205. log.Println("redisutil-GetNewBytesError", err)
  206. } else if r != nil {
  207. if tmp, ok := r.([]byte); ok {
  208. ret = &tmp
  209. }
  210. }
  211. return
  212. }
  213. //删所有key
  214. func FlushDB(code string) bool {
  215. b := false
  216. defer catch()
  217. conn := RedisPool[code].Get()
  218. defer conn.Close()
  219. var err error
  220. _, err = conn.Do("FLUSHDB")
  221. if nil != err {
  222. log.Println("redisutil-FLUSHDBError", err)
  223. } else {
  224. b = true
  225. }
  226. return b
  227. }
  228. //支持删除多个key
  229. func Del(code string, key ...interface{}) bool {
  230. defer catch()
  231. b := false
  232. conn := RedisPool[code].Get()
  233. defer conn.Close()
  234. var err error
  235. _, err = conn.Do("DEL", key...)
  236. if nil != err {
  237. log.Println("redisutil-DELError", err)
  238. } else {
  239. b = true
  240. }
  241. return b
  242. }
  243. /**
  244. func DelKey(key ...interface{}) {
  245. defer func() {
  246. if r := recover(); r != nil {
  247. log.Println("[E]", r)
  248. for skip := 1; ; skip++ {
  249. _, file, line, ok := runtime.Caller(skip)
  250. if !ok {
  251. break
  252. }
  253. go log.Printf("%v,%v\n", file, line)
  254. }
  255. }
  256. }()
  257. for i := 0; i < len(RedisPool); i++ {
  258. delByNum(i, key...)
  259. }
  260. }
  261. **/
  262. /**
  263. func delByNum(n int, key ...interface{}) {
  264. defer func() {
  265. if r := recover(); r != nil {
  266. log.Println("[E]", r)
  267. for skip := 1; ; skip++ {
  268. _, file, line, ok := runtime.Caller(skip)
  269. if !ok {
  270. break
  271. }
  272. go log.Printf("%v,%v\n", file, line)
  273. }
  274. }
  275. }()
  276. i := 0
  277. for _, v := range RedisPool {
  278. if i == n {
  279. conn := v.Get()
  280. defer conn.Close()
  281. conn.Do("DEL", key...)
  282. break
  283. }
  284. i++
  285. }
  286. }
  287. **/
  288. //根据代码和前辍key删除多个
  289. func DelByCodePattern(code, key string) {
  290. defer catch()
  291. conn := RedisPool[code].Get()
  292. defer conn.Close()
  293. ret, err := conn.Do("KEYS", key)
  294. var result []interface{}
  295. if nil != err {
  296. log.Println("redisutil-GetError", err)
  297. } else {
  298. result = ret.([]interface{})
  299. for k := 0; k < len(result); k++ {
  300. conn.Do("DEL", string(result[k].([]uint8)))
  301. }
  302. }
  303. }
  304. /**
  305. func DelByPattern(key string) {
  306. defer func() {
  307. if r := recover(); r != nil {
  308. log.Println("[E]", r)
  309. for skip := 1; ; skip++ {
  310. _, file, line, ok := runtime.Caller(skip)
  311. if !ok {
  312. break
  313. }
  314. go log.Printf("%v,%v\n", file, line)
  315. }
  316. }
  317. }()
  318. i := 0
  319. for _, v := range RedisPool {
  320. conn := v.Get()
  321. defer conn.Close()
  322. ret, err := conn.Do("KEYS", key)
  323. var result []interface{}
  324. if nil != err {
  325. log.Println("redisutil-GetError", err)
  326. } else {
  327. result = ret.([]interface{})
  328. for k := 0; k < len(result); k++ {
  329. delByNum(i, string(result[k].([]uint8)))
  330. }
  331. }
  332. i++
  333. }
  334. }
  335. **/
  336. //自增计数器
  337. func Incr(code, key string) int64 {
  338. ret, err := IncrByErr(code, key)
  339. if nil != err {
  340. log.Println("redisutil-INCR-Error", err)
  341. }
  342. return ret
  343. }
  344. //自增计数器
  345. func IncrByErr(code, key string) (int64, error) {
  346. defer catch()
  347. conn := RedisPool[code].Get()
  348. defer conn.Close()
  349. ret, err := conn.Do("INCR", key)
  350. if nil != err {
  351. return 0, err
  352. }
  353. if res, ok := ret.(int64); ok {
  354. return res, nil
  355. } else {
  356. return 0, nil
  357. }
  358. }
  359. //自减
  360. func Decrby(code, key string, val int) int64 {
  361. defer catch()
  362. conn := RedisPool[code].Get()
  363. defer conn.Close()
  364. ret, err := conn.Do("DECRBY", key, val)
  365. if nil != err {
  366. log.Println("redisutil-DECR-Error", err)
  367. } else {
  368. if res, ok := ret.(int64); ok {
  369. return res
  370. } else {
  371. return 0
  372. }
  373. }
  374. return 0
  375. }
  376. //根据正则去取
  377. func GetKeysByPattern(code, key string) []interface{} {
  378. defer catch()
  379. conn := RedisPool[code].Get()
  380. defer conn.Close()
  381. ret, err := conn.Do("KEYS", key)
  382. if nil != err {
  383. log.Println("redisutil-GetKeysError", err)
  384. return nil
  385. } else {
  386. res, _ := ret.([]interface{})
  387. return res
  388. }
  389. }
  390. //批量取多个key
  391. func Mget(code string, key []string) []interface{} {
  392. defer catch()
  393. conn := RedisPool[code].Get()
  394. defer conn.Close()
  395. interfaceKeys := make([]interface{}, len(key))
  396. for n, k := range key {
  397. interfaceKeys[n] = k
  398. }
  399. ret, err := conn.Do("MGET", interfaceKeys...)
  400. if nil != err {
  401. log.Println("redisutil-MgetError", err)
  402. return nil
  403. } else {
  404. res, _ := ret.([]interface{})
  405. return res
  406. }
  407. }
  408. //取出并删除Key
  409. func Pop(code string, key string) (result interface{}) {
  410. defer catch()
  411. conn := RedisPool[code].Get()
  412. defer conn.Close()
  413. ret, err := conn.Do("GET", key)
  414. if nil != err {
  415. log.Println("redisutil-PopError", err)
  416. } else {
  417. var ok bool
  418. var res []byte
  419. if res, ok = ret.([]byte); ok {
  420. err = json.Unmarshal(res, &result)
  421. if err != nil {
  422. log.Println("Poperr", err)
  423. }
  424. }
  425. conn.Do("DEL", key)
  426. }
  427. return
  428. }
  429. //list操作
  430. func LPOP(code, list string) (result interface{}) {
  431. defer catch()
  432. conn := RedisPool[code].Get()
  433. defer conn.Close()
  434. ret, err := conn.Do("LPOP", list)
  435. if nil != err {
  436. log.Println("redisutil-LPopError", err)
  437. } else {
  438. if res, ok := ret.([]byte); ok {
  439. err = json.Unmarshal(res, &result)
  440. log.Println(err)
  441. }
  442. }
  443. return
  444. }
  445. func RPUSH(code, list string, val interface{}) bool {
  446. defer catch()
  447. conn := RedisPool[code].Get()
  448. defer conn.Close()
  449. _obj, _ := json.Marshal(val)
  450. _, err := conn.Do("RPUSH", list, _obj)
  451. if nil != err {
  452. log.Println("redisutil-RPUSHError", err)
  453. return false
  454. }
  455. return true
  456. }
  457. func LLEN(code, list string) int64 {
  458. defer catch()
  459. conn := RedisPool[code].Get()
  460. defer conn.Close()
  461. ret, err := conn.Do("LLEN", list)
  462. if nil != err {
  463. log.Println("redisutil-LLENError", err)
  464. return 0
  465. }
  466. if res, ok := ret.(int64); ok {
  467. return res
  468. } else {
  469. return 0
  470. }
  471. }
  472. //向有序集合添加一个,或者更新已存在成员的分数
  473. func Zadd(code, key string, score float64, value string) int64 {
  474. defer catch()
  475. conn := RedisPool[code].Get()
  476. defer conn.Close()
  477. ret, err := conn.Do("ZADD", key, score, value)
  478. if nil != err {
  479. log.Println("redisutil-Zadd error", err)
  480. return -1
  481. }
  482. if res, ok := ret.(int64); ok {
  483. return res
  484. } else {
  485. return -1
  486. }
  487. }
  488. //返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。
  489. func Zrevrangebyscore(code, key string, max, min interface{}) []string {
  490. defer catch()
  491. conn := RedisPool[code].Get()
  492. defer conn.Close()
  493. ret, err := conn.Do("ZREVRANGEBYSCORE", key, max, min)
  494. r := []string{}
  495. if nil != err {
  496. log.Println("redisutil-ZREVRANGEBYSCORE error", err)
  497. return r
  498. }
  499. if res, ok := ret.([]interface{}); ok {
  500. for _, v := range res {
  501. r = append(r, string(v.([]uint8)))
  502. }
  503. }
  504. return r
  505. }
  506. //返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。
  507. func Zrangebyscore(code, key string, min, max interface{}) []string {
  508. defer catch()
  509. conn := RedisPool[code].Get()
  510. defer conn.Close()
  511. ret, err := conn.Do("ZRANGEBYSCORE", key, min, max, "WITHSCORES")
  512. r := []string{}
  513. if nil != err {
  514. log.Println("redisutil-ZRANGEBYSCORE error", err)
  515. return r
  516. }
  517. if res, ok := ret.([]interface{}); ok {
  518. for _, v := range res {
  519. r = append(r, string(v.([]uint8)))
  520. }
  521. }
  522. return r
  523. }
  524. //移除有序集合中的一个或多个成员
  525. func Zrem(code, key string, member ...string) int64 {
  526. defer catch()
  527. conn := RedisPool[code].Get()
  528. defer conn.Close()
  529. args := []interface{}{key}
  530. for _, v := range member {
  531. args = append(args, v)
  532. }
  533. ret, err := conn.Do("ZREM", args...)
  534. if nil != err {
  535. log.Println("redisutil-ZREM error", err)
  536. return -1
  537. }
  538. if res, ok := ret.(int64); ok {
  539. return res
  540. }
  541. return -1
  542. }
  543. //返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。
  544. func Zrank(code, key, member string) int64 {
  545. defer catch()
  546. conn := RedisPool[code].Get()
  547. defer conn.Close()
  548. ret, err := conn.Do("ZRANK", key, member)
  549. if nil != err {
  550. log.Println("redisutil-ZRANK error", err)
  551. return -1
  552. }
  553. if res, ok := ret.(int64); ok {
  554. return res
  555. }
  556. return -1
  557. }
  558. //返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
  559. func Zrevrank(code, key, member string) int64 {
  560. defer catch()
  561. conn := RedisPool[code].Get()
  562. defer conn.Close()
  563. ret, err := conn.Do("ZREVRANK", key, member)
  564. if nil != err {
  565. log.Println("redisutil-ZREVRANK error", err)
  566. return -1
  567. }
  568. if res, ok := ret.(int64); ok {
  569. return res
  570. }
  571. return -1
  572. }
  573. //返回有序集中,成员的分数值
  574. func Zscore(code, key, member string) string {
  575. defer catch()
  576. conn := RedisPool[code].Get()
  577. defer conn.Close()
  578. ret, err := conn.Do("ZSCORE", key, member)
  579. if nil != err {
  580. log.Println("redisutil-ZSCORE error", err)
  581. return ""
  582. }
  583. if res, ok := ret.([]uint8); ok {
  584. return string(res)
  585. }
  586. return ""
  587. }
  588. //有序集合中对指定成员的分数加上增量 increment
  589. func Zincrby(code, key string, increment float64, member string) int64 {
  590. defer catch()
  591. conn := RedisPool[code].Get()
  592. defer conn.Close()
  593. ret, err := conn.Do("ZINCRBY", key, increment, member)
  594. if nil != err {
  595. log.Println("redisutil-ZINCRBY error", err)
  596. return -1
  597. }
  598. if res, ok := ret.(int64); ok {
  599. return res
  600. }
  601. return -1
  602. }
  603. func catch() {
  604. if r := recover(); r != nil {
  605. log.Println(r)
  606. for skip := 0; ; skip++ {
  607. _, file, line, ok := runtime.Caller(skip)
  608. if !ok {
  609. break
  610. }
  611. go log.Printf("%v,%v\n", file, line)
  612. }
  613. }
  614. }
  615. //获取到期时间 -1未设置时间永久 -2到期
  616. func GetTTL(code, key string) int64 {
  617. defer catch()
  618. conn := RedisPool[code].Get()
  619. defer conn.Close()
  620. ret, err := conn.Do("TTL", key)
  621. if nil != err {
  622. log.Println("redisutil-GetError", err)
  623. return 0
  624. }
  625. if res, ok := ret.(int64); ok {
  626. return res
  627. }
  628. return 0
  629. }