乐观锁与悲观锁

本文引用自Elasticsearch的版本控制

变化越是频繁,或读取和更新间的时间越长,越容易丢失我们的更改。

在数据库中,有两种通用的方法确保在并发更新时修改不丢失:

悲观并发控制(Pessimistic concurrency control)

这在关系型数据库中被广泛的使用,假设冲突的更改经常发生,为了解决冲突我们把访问区块化。典型的例子是在读一行数据前锁定这行,然后确保只有加锁的那个线程可以修改这行数据。

乐观并发控制(Optimistic concurrency control):

被Elasticsearch使用,假设冲突不经常发生,也不区块化访问,然而,如果在读写过程中数据发生了变化,更新操作将失败。这时候由程序决定在失败后如何解决冲突。实际情况中,可以重新尝试更新,刷新数据(重新读取)或者直接反馈给用户。

乐观并发控制

Elasticsearch是分布式的。当文档被创建、更新或删除,文档的新版本会被复制到集群的其它节点。Elasticsearch即是同步的又是异步的,意思是这些复制请求都是平行发送的,并无序(out of sequence)的到达目的地。这就需要一种方法确保老版本的文档永远不会覆盖新的版本。

上文我们提到indexgetdelete请求时,我们指出每个文档都有一个_version号码,这个号码在文档被改变时加一。Elasticsearch使用这个_version保证所有修改都被正确排序。当一个旧版本出现在新版本之后,它会被简单的忽略。

我们利用_version的这一优点确保数据不会因为修改冲突而丢失。我们可以指定文档的version来做想要的更改。如果那个版本号不是现在的,我们的请求就失败了。

Let’s create a new blog post: 让我们创建一个新的博文:

PUT /website/blog/1/_create
{
  "title": "My first blog entry",
  "text":  "Just trying this out..."
}

响应体告诉我们这是一个新建的文档,它的_version1。现在假设我们要编辑这个文档:把数据加载到web表单中,修改,然后保存成新版本。

首先我们检索文档:

GET /website/blog/1

响应体包含相同的_version1

{
  "_index" :   "website",
  "_type" :    "blog",
  "_id" :      "1",
  "_version" : 1,
  "found" :    true,
  "_source" :  {
      "title": "My first blog entry",
      "text":  "Just trying this out..."
  }
}

现在,当我们通过重新索引文档保存修改时,我们这样指定了version参数:

PUT /website/blog/1?version=1 <1>
{
  "title": "My first blog entry",
  "text":  "Starting to get the hang of this..."
}
  • <1> 我们只希望文档的_version1时更新才生效。

This request succeeds, and the response body tells us that the _version has been incremented to 2:

请求成功,响应体告诉我们_version已经增加到2

{
  "_index":   "website",
  "_type":    "blog",
  "_id":      "1",
  "_version": 2
  "created":  false
}

然而,如果我们重新运行相同的索引请求,依旧指定version=1,Elasticsearch将返回409 Conflict状态的HTTP响应。响应体类似这样:

{
  "error" : "VersionConflictEngineException[[website][2] [blog][1]:
             version conflict, current [2], provided [1]]",
  "status" : 409
}

这告诉我们当前_version2,但是我们指定想要更新的版本是1

我们需要做什么取决于程序的需求。我们可以告知用户其他人修改了文档,你应该在保存前再看一下。而对于上文提到的商品stock_count,我们需要重新检索最新文档然后申请新的更改操作。

所有更新和删除文档的请求都接受version参数,它可以允许在你的代码中增加乐观锁控制。

附上Elasticsearch中文文档地址 http://es.xiaoleilu.com/

当使用悲观锁的时候可以使用 RabbitMQ 消息队列 http://blog.csdn.net/anzhsoft/article/details/19563091

php创建真正的777权限的文件夹

最近的服务器环境不知道什么情况,runtime的Cache用户组由www:www变成了root:root,大爷的,暂时还没找到什么原因,这样就写入不进去了,看了下Cache目录755,www用户是other,所以就是r+x,没有w权限,去他大爷的,最后查了下虽然mkdir中的参数设置的是0777,但是由于umask问题导致只能创建到755,但是chmod却可以设置成777,但是mkdir文件夹时直接创建到了 Runtime/Cache/Home 在这里只有Home是777,前面的Cache还是755,所以在Cache创建时,先递归创建777的Cache目录,这样就有写的权限了。

  • mkdir 创建的文件夹受到umask影响,需要再chmod下
  • mkdir 可以递归创建目录,再chmod,只是最后的文件夹是777,前面的还是755,可递归创建/chmod

记录一次php slow log 的线上问题

早上刚刚看完大阅兵,中午吃个午饭,睡个小觉,突然一阵提醒来袭,刷刷刷,说服务器挂了,立马起来,看了下主要的业务,没问题啊,大爷的,真坑,当时看了下RDS,连接数上来了,

“show processlist”|wc -l

又看了下是什么导致的,丫的,一堆sleep,那就差不多是哪个php地方被堵死了,

还好以前开启的php-fpm 的slowlog

request_slowlog_timeout = 5
slowlog = /data/wwwlogs/today/php-slow.log

查了下,是跨域请求别人的服务导致的,其实我这边已经做了缓存,但是缓存过期后,就会直接去请求别人服务,别人服务一挂,那我这个也就傻逼了,那只好在我这边做个数据库缓存,定时去刷到数据库中,那样就不会有依赖了

好吧。。。

苦逼的程序员