【问题标题】:Datastore persistence is one behind数据存储持久性落后
【发布时间】:2013-10-13 23:03:03
【问题描述】:

我有以下非常简单的代码来将字符串保存在datastore 中。我从各种datastore 示例中将其汇总,但我仍然对此不满意。

其目的只是将字符串存储在persist 中的键下,然后在fromPresistence 下检索它。

// Used to store the string value.
type Entity struct {
    Value string
}

// Grow my key.
func key(x string) *datastore.Key {
    return datastore.NewKey(context, "Persist", x, 0, nil)
}

// Get it from persistence storage.
func fromPersistence(x string) string {
    var persisted string = x
    // Make my key.
    k := key(x)
    // New entity for filling in.
    e := new(Entity)
    // Look it up!
    if err := datastore.Get(context, k, e); err == nil {
        // It was there!
        persisted = e.Value
        context.Debugf("Persisted %s=%s", x, persisted)
    }

    return persisted
}

// Persist the latest number.
func persist(x string) func(*big.Int) {
    return func(n *big.Int) {
        // Make my key.
        k := key(x)
        // New entity for filling in.
        e := new(Entity)
        // Value is the decimal form of the number.
        e.Value = n.String()
        context.Debugf("Persist %s=%s", start, e.Value)
        if _, err := datastore.Put(context, k, e); err != nil {
            context.Debugf("Persist failed! %s", err)
        }
    }
}

但它似乎每次都落后一个。以下是一些日志结果:

C:\Go\GAE\go_appengine\google\src>\go\gae\go_appengine\dev_appserver.py unique/
INFO     2013-10-15 20:55:08,296 sdk_update_checker.py:245] Checking for updates to the SDK.
INFO     2013-10-15 20:55:09,726 api_server.py:138] Starting API server at: http://localhost:50218
INFO     2013-10-15 20:55:09,746 dispatcher.py:168] Starting module "default" running at: http://localhost:8080
INFO     2013-10-15 20:55:09,763 admin_server.py:117] Starting admin server at: http://localhost:8000
INFO     2013-10-15 20:56:22,131 module.py:599] default: "GET / HTTP/1.1" 304 -
INFO     2013-10-15 20:56:22,344 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 -
INFO     2013-10-15 20:56:22,448 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 -
2013/10/15 20:56:26 DEBUG: Persisted 38913371956013078496870267859=3378577588146889866220112993
2013/10/15 20:56:26 DEBUG: Persist 38913371956013078496870267859=21186844412818184262771263024
...
2013/10/15 20:56:30 DEBUG: Persist 38913371956013078496870267859=1324177775801136516423203939
INFO     2013-10-15 20:56:30,756 module.py:599] default: "GET /n HTTP/1.1" 200 19
INFO     2013-10-15 20:56:30,927 module.py:599] default: "GET /favicon.ico HTTP/1.1" 304 -
2013/10/15 20:56:32 DEBUG: Persist 38913371956013078496870267859=20778614526287997725322370609

C:\Go\GAE\go_appengine\google\src>\go\gae\go_appengine\dev_appserver.py unique/
INFO     2013-10-15 20:57:15,657 sdk_update_checker.py:245] Checking for updates to the SDK.
INFO     2013-10-15 20:57:17,033 api_server.py:138] Starting API server at: http://localhost:50241
INFO     2013-10-15 20:57:17,085 dispatcher.py:168] Starting module "default" running at: http://localhost:8080
INFO     2013-10-15 20:57:17,098 admin_server.py:117] Starting admin server at: http://localhost:8000
2013/10/15 20:57:24 DEBUG: Persisted 38913371956013078496870267859=1324177775801136516423203939
2013/10/15 20:57:24 DEBUG: Persist 38913371956013078496870267859=20778614526287997725322370609
...

查看最后一次持久化尝试如何存储 20778614526287997725322370609,但检索尝试返回之前的持久化值 1324177775801136516423203939

我做错了什么?

注意:我已经更改了代码以使用context.Debugf 机制来打印我的调试字符串,从而将奇怪的日志记录排除在外。

旧的Logf 代码如下。我确信这是奇怪日志条目的原因。这不是我的问题的目标。我会自己解决这个问题。

func Logf(format string, a ...interface{}) {
    if context != nil {
        // Context is valid.
        if len(logQueue) > 0 {
            // Roll out the stored entries.
            for i := 0; i < len(logQueue); i++ {
                context.Debugf("%s", logQueue[i])
            }
            // Empty the queue.
            logQueue = make([]string, 0)
        }
        // Pass a "" to just flush the queue
        if format != "" {
            // Log it through the context.
            context.Debugf(format, a)
        }
    } else {
        // No context! Queue it up.
        logQueue = append(logQueue, fmt.Sprintf(format, a...))
    }

}

【问题讨论】:

  • 这些不是相同的打印语句。没有“[]”
  • 我知道这听起来像是一个愚蠢的问题,但您是否在任何地方使用基于1 的索引?这只是 感觉 就像它从切片中提取了错误的值,并且索引偏离了 1。也许在NewKey 函数中?
  • 我计划稍后发布我的Logf 函数,以消除这里发生切片/数组的想法。我相信格式和MISSING 注释纯粹是一个红鲱鱼。请注意,键始终为x string,返回的值始终为string
  • @Intermernet - 我不认为这是一个单独的问题 - 但显然我可能错了。这只是我尝试使用 GAE datastore 系统进行简单的 Key/Value 存储。
  • @Intermernet - 已编辑问题以消除日志记录问题。抱歉打扰了。

标签: google-app-engine go


【解决方案1】:

查看您的数据存储代码...它以某种方式将值与键一起存储。

语句

Logf("Persist %s=%s", x, e.Value)

正在生成:

2013/10/13 23:21:26 DEBUG: Persist [38913371956013078496870267859 19124562091635092830747528895]=%s(MISSING)

这意味着您的“x”值有一个键的一部分和一些其他值(从您的文本来看,它似乎是前一个键值)。

缺少实际值...这就是%s(MISSING) 位的含义

【讨论】:

  • 说得好,但我认为 ...MISSING 的东西只是我对fmt 不熟悉。这些功能正常工作 - 唯一的问题是始终存在单项滞后。 PersistPersisted 的日志记录相同的事实表明它甚至可能是我的日志记录机制有问题。
  • 我会更正日志系统,以便您在依靠它来诊断系统的另一部分之前从中获得可靠的答案。当您报告它的日志记录功能如此损坏时,真的很难看出您的单项滞后来自哪里......当它显然不是时,您保证“它工作正常”有点可疑;)
  • 只是为了澄清一下:对于每种情况,e.Value 中的实际内容是什么?您的日志函数说它丢失了,并且您返回的键值是字符串切片。当可用信息如此混乱时,很难看到发生了什么;)您是否为此功能编写了任何测试用例?
【解决方案2】:

这里有一个很好的机会,您看到的是分布式系统的那些意想不到的方面之一。如果您对persistfromPersistence 的调用最终在您的应用程序的不同实例上运行,则日志消息可能会采用稍微不同的路径到达它们持续存在的位置。请注意,看似颠倒的日志消息上的时间戳是相同的。

【讨论】:

  • Logf 系统可能会延迟记录的实际记录,直到 Context 可用于记录。因此时间戳不可靠。不过有趣的想法。但是,我怀疑这不是时间问题 - 每次都会出现滞后,始终如一。
  • 我现在已经确认,同样的问题发生在实时站点上 - 而不仅仅是在本地模拟器中。我认为我没有看到不同的线程/实例 - 我希望这只会偶尔显示,我每次都会看到它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-07-25
  • 2011-02-28
  • 1970-01-01
  • 1970-01-01
  • 2020-07-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多