Akka 用于复杂主键的安全persistenceId编码器

Akka 用于复杂主键的安全persistenceId编码器,akka,akka-persistence,Akka,Akka Persistence,从复合键(字符串,字符串)生成persistenceId的最佳方法是什么?该键的每个部分都不受控制(可能包含任何符号) 如果需要解码 如果不需要解码(原始密钥存储在actor中) 一种可能是将键的第一个字符串的长度编码为persistenceId的第一个字符。Scala中的一个示例: import scala.util.Try type ComplexKey = (String, String) def persistenceIdFor(key: ComplexKey): String =

复合键
(字符串,字符串)生成
persistenceId
的最佳方法是什么?该键的每个部分都不受控制(可能包含任何符号)

  • 如果需要解码
  • 如果不需要解码(原始密钥存储在actor中)

  • 一种可能是将键的第一个字符串的长度编码为
    persistenceId
    的第一个字符。Scala中的一个示例:

    import scala.util.Try
    
    type ComplexKey = (String, String)
    
    def persistenceIdFor(key: ComplexKey): String = {
      val (first, second) = key
      val firstLen = first.length
      s"${firstLen};${first},${second}"
    }
    
    val PersistenceIdRegex = """^(\d+);(.*)$""".r
    
    // You might not necessarily ever need to get a key for a given persistenceId, but to show the above is invertible
    def keyForPersistenceId(persistenceId: String): Option[ComplexKey] =
      persistenceId match {
        case PersistenceIdRegex(firstLenStr, content) =>
          val firstLenTry = Try(firstLenStr.toInt)
    
          firstLenTry
            .filter(_ <= content.length)
            .toOption
            .map(firstLen => content.splitAt(firstLen))
    
        case _ => None
      }
    
    导入scala.util.Try
    类型ComplexKey=(字符串,字符串)
    def persistenceIdFor(键:ComplexKey):字符串={
    val(第一,第二)=键
    val firstLen=first.length
    s“${firstLen};${first},${second}”
    }
    val PersistenceIdRegex=“”^(\d+);(.*)$”。r
    //您可能不一定需要为给定的persistenceId获取密钥,但要显示上述内容是可逆的
    def keyForPersistenceId(persistenceId:String):选项[ComplexKey]=
    持久性ID匹配{
    案例持久性IDregex(firstLenStr,内容)=>
    val firstLenTry=Try(firstLenStr.toInt)
    初学
    .filter(ucontent.splitAt(firstLen))
    案例=>无
    }
    
    另一种可能是使用转义,但这可能有很多微妙之处,尽管它最初看起来很简单


    正在使用的特定Akka持久性后端可能会对
    持久性ID实施限制(例如ID的长度)。

    感谢您提供的示例和对特定Akka持久性后端
    的评论。“钥匙不受控制(可能包含任何符号)”如何。我认为这些部分必须被编码,但如何编码呢?
    Base64URL
    是正确的选择吗?PersistenceId将取决于Cassandra的PK长度限制我也认为hash是PersistenceId,但参与者将有一个原始PK列表,每个PK都应该有自己的状态。据我所知,字符串中的任何内容都是普通Akka持久性后端中的有效字符,因此我没有理由将其设为base64(如果没有其他内容,则可能会延长字符串)。默认情况下,Akka Persistence Cassandra使用
    text
    作为
    persistenceId
    的列类型,因此这是2GB的限制(由于主键包含一些较小的列,因此略小于此限制)。至于使用散列,你可以这样做,特别是当你在参与者的持久状态下存储散列内容时。只需小心不要使用
    hashCode
    ##
    方法,因为这些方法不能保证一致性:显式地选择像Murruil3这样的方法作为散列算法,并坚持使用它将近一年在常见的Akka持久化后端中,我所知道的最严格的
    persistenceId
    长度限制是Postgres上的JDBC,它有255个字符的限制。