Redis 功能入门大全和基于scala实现示例(2)- redis读写实现

redis-scala.PNG

概要

  • Redis server 基于5.0.0的stable版本
  • Client基于 Jedis 2.9.0
  • Scala 基于 2.11.X

文章链接:

Redis 功能入门大全和基于scala的应用实现(1)
Redis 功能入门大全和基于scala的应用实现(2)

在系列的文章完成后,我们了解redis的基本功能,实现scala语言对redis进行的基本操作,让你基于scala完成开发工作。

本文内容:

  • 使用scala实现redis数据的读写。具体:使用Redis提供Hash表的API来对数据进行读写,提供redis对数据访问的基本思路。redis不同模式下访问方式,后面文章会专门描述。
  • 读写性能对比
  • scala 编码和环境搭建遇到的问题

如何访问Redis数据?

Redis基础功能是数据读写和数据复制机制,除此之外包含运维工具、性能提升pipeline、事务于Lua脚本等。'Redis服务读写是主体功能。'

使用Hash散列表对数据进行读写,结合jedis 和 scala代码说明不同读写方式方法。
本节描述使用jedis对redis服务进行读写操作,不同模式下Redis读写API基本相同,因此后面不在说明。

Redis服务端只提供读写服务,访问数据则需要客户端。开源组件有多款软件支持redis访问,Jedis是我们访问redis服务的客户端。

scala是如何现实不同方式的读写哪?下面逐步说明:

  • Jedis读操作实现API

在数据操作上,Redis服务端hash类型数据处理API是统一的,即不同的服务类型对数据操作API一致。因此,scala实现读写操作所有模式都相同,不同模式编码层面的差异在于redis连接创建和释放。

  • 读操作

    事务和pipeline是redis提供提升读写性能方法,各有特点根据需要使用。

 //using 功能是获取连接,执行完成后,关闭连接
 trait Using{
  type Close = {def close():Unit} //定义新的类型

  def using[T <: Close,M](pa: T)(f:T => M): Unit = {
    f(pa)
    pa.close()
  }
}
//按照key读取数据
   def readHGet(keys: List[String]) = {
    using(connection) {
      conn =>
        keys.foreach {
          el => conn.hgetAll(el)
        }
    }
  }
  //读取所有key
  def readKeys = {
    using(connection) {
      conn =>
       conn.keys("*")
    }
  }
//使用pipeline的方式对数据进行读写
  def readPipeline(keys: List[String]): Unit = {
    using(connection) {
      conn =>
      val p = conn.pipelined()
      keys.foreach {
        el => p.hgetAll(el)
      }
      p.sync()
    }
  }
  • 写入操作
//对数据的写入操作,获取的jedis连接没有关闭连接
trait RedisAction  {
 //多个hash数据写入
 def writeHMset(data: List[(String, util.HashMap[String, String])], conn: Jedis) = {
    data.foreach {
      case (key, data)  =>
        conn.hmset(key, data)
    }
  }
//使用pipeline方式写入数据
def pipelineHash(data: List[(String, util.HashMap[String, String])], conn: Jedis) = {
    val p = conn.pipelined()
    data.foreach {
      case (key, dt) =>
        p.hmset(key, dt)
    }
    p.sync() //without response
  }

//without watch/unwatch
//使用事务方式写数据
def transactionHash(data: List[(String, util.HashMap[String, String])], conn: Jedis) = {
    val t: Transaction = conn.multi()
    data.foreach {
      case (key, data)  =>
        t.hmset(key, data)
    }
    t.exec()
  }
}

jedis操作没有保证数据数据一致,因此以上redis数据读写接口在单一的客户端使用正常。多客户端并发读写会存在数据不一致的情况。这需要 Redis分布式锁解决,见后面章节。

  • 测试性能数据

    写入的类型是Hash,每个Key包含多个field。测试数据来自主从模式下,受网卡带宽制约。

    操作方式 \读写 数据数量 耗时(秒) 速度 其它
    逐条插入 13983 21 665 pcs
    pipeline 批量写 19698 0.35 56280pcs 100mbs网卡出现瓶颈,写入慢
    事务 批量写 19698 0.36 56280pcs 100mbs网卡出现瓶颈,写入慢
    逐条读 19698 32.74 615 pcs
    pipeline 批量读 52386 0.33 158745 pcs
    事务 批量读 52386 0.35 158745 pcs
  • Jedis连接遇到的问题列表

  • [ src]# ./redis-server ../redis_6380.conf slaveof 127.0.0.1 6380
    1410:C 05 Nov 2018 15:54:06.132 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
    1410:C 05 Nov 2018 15:54:06.132 # Redis version=5.0.0, bits=64, commit=00000000, modified=0, pid=1410, just started
    1410:C 05 Nov 2018 15:54:06.132 # Configuration loaded
    1410:S 05 Nov 2018 15:54:06.133 # Creating Server TCP listening socket 127.0.0.1:6380: bind: Address already in use

rebind port

原因: redis.conf中存在bind参数,指定能够访问本机的IP.在创建实例是不是绑定的127.0.01导致异常,改成绑定IP即可。

  • 创建连接池失败 默认密码不能为空,否则 使用该接口创建失败

jedis Caused by: java.net.SocketTimeoutException: Read timed out

原因:

JedisPool(conf, host, port, timeOut, password, database, clientName, true)

ssh 安全连接设置不能为true, 密码不能为空.

redis.clients.jedis.exceptions.JedisDataException: Please close pipeline or multi block before calling this method.

原因:Redis事务的执行结果是在exec之后才统一返回,所以Jedis会用一个Response对象最为事务对象transaction的执行放回值。如果我们在transaction执行exec方法之前调用response对象的get方法会出现异常。

总结

本文实现:

  • redis 读写各种接口,可以直接编译运行
  • 各个接口性能测试指标对比
  • 遇到故障及其解决方法

往期传送门:

Redis 功能入门大全和基于scala的应用实现(1)
Redis 功能入门大全和基于scala的应用实现(2)
Redis 功能入门大全和基于scala实现示例(3)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,326评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,228评论 1 304
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,979评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,489评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,894评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,900评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,075评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,803评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,565评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,778评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,255评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,582评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,254评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,151评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,952评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,035评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,839评论 2 277

推荐阅读更多精彩内容