代码人生

开发人员必须知道的关于Couchbase的10件事

代码人生 http://www.she9.com 2018-08-13 15:57 出处:网络 编辑:@技术狂热粉
CouchbaseServer5.0和5.5是两个大版本。让我们看看一些开发人员不能错过的新功能和旧功能:

Couchbase Server 5.0和5.5是两个大版本。让我们看看一些开发人员不能错过的新功能和旧功能:


1)子文档


这个特性已经存在了一段时间,但仍然值得提及。一些键值存储只允许您将整个文档组合在一起,这是一个合理的特性。毕竟,它是键值存储。但是,如果使用Couchbase作为KV,仍然可以通过指定到它的路径来操作文档的部分内容。例:


给定以下文件:

        {        
          "name": "Douglas Reynholm",
          "email": "douglas@reynholmindustries.com",
          "addresses": {
            "billing": {
              "line1": "123 Any Street",
              "line2": "Anytown",
              "country": "United Kingdom"
            },
            "delivery": {
              "line1": "123 Any Street",
              "line2": "Anytown",
              "country": "United Kingdom"
            }
          },
          "purchases": {
            "complete": [
              339, 976, 442, 666
            ],
            "abandoned": [
              157, 42, 999
            ]
          }
        }

您可以通过简单地指定到文档的路径来操作文档的某些部分,比如GET('address .billing')或ARRAY_APPEND('purchases.abandoned', 42)


如果你想读更多,可以看看这篇博客或者官方文档。

2)事件


在Couchbase 5.5中,Eventing显然是最酷的功能之一,我们已经有很多博客报道过了,比如这里或这里。对于那些还没有听说过的人来说,Eventing服务使您能够编写服务器端函数,这些函数在插入/更新/删除文档时自动触发。这些函数可以很容易地使用类似javascript的语法编写:

开发人员必须知道的关于Couchbase的10件事

此外,您还可以通过curl调用应用程序中的endpoint:

        function OnUpdate(doc, meta) {        
          if (doc.resourceType != 'Observation') return;
         
          let reference = doc.subject.reference;
          let url = "http://localhost:8080/events/" + reference.substr(9);
          let data = JSON.stringify({
            "reference": doc.subject.reference,
            "code": doc.code.coding[0].code,
            "recordedAt": doc.issued,
            "value": doc.valueQuantity.value
          });
         
          let curl = SELECT CURL($url, {
            "request": "POST",
            "header": [ "Content-Type: application/json", "accept: application/json" ],
            "data": $data
          });
         
          curl.execQuery();
        }
         
        function OnDelete(meta) {}

3)ANSI连接


Couchbase允许您在查询中使用连接很长时间,但到目前为止,它只能通过使用我们自己的语法来完成。由于Couchbase 5.5,您还可以使用ANSI连接语法:

        SELECT DISTINCT route.destinationairport        
        FROM `travel-sample` airport JOIN `travel-sample` route
             ON airport.faa = route.sourceairport
                AND route.type = "route"
        WHERE airport.type = "airport"
          AND airport.city = "San Francisco"
          AND airport.country = "United States";

4)全文检索


大多数面向用户的应用程序最终都需要实现某种高级搜索。这种特性通常要求您将数据推送到第三方工具,比如Solr或Elastic Search。然而,添加这样的工具大大增加了基础设施的成本和复杂性,更不用说将对象/文档更改推入这些工具所需的所有代码了。


从Couchbase 5.0开始,您只需在web控制台中创建全文搜索索引,然后直接从数据库进行全文搜索:

开发人员必须知道的关于Couchbase的10件事

高亮搜索结果:


开发人员必须知道的关于Couchbase的10件事


如何通过SDK进行简单搜索:

            @Override        
            public List<SearchQueryRow> searchQuery(String word) {
                String indexName = "movies_index";
                QueryStringQuery query = SearchQuery.queryString(word);
        
                SearchQueryResult result = movieRepository.getCouchbaseOperations().getCouchbaseBucket().query(
                        new SearchQuery(indexName, query).highlight().limit(20));
        
                List<SearchQueryRow> hits = new ArrayList<>();
                if (result != null && result.errors().isEmpty()) {
                    Iterator<SearchQueryRow> resultIterator = result.iterator();
                    while (resultIterator.hasNext()) {
                        hits.add(resultIterator.next());
                    }
                }
                return hits;
            }

5) 更快的查询Queries, GROUP BYs, and Aggregation Pushdown

不管数据库是什么,聚合(min、max、avg等)和GROUP BYs操作在性能方面一直存在问题。为了解决这个问题,使用Couchbase 5.5,您可以利用索引来加速这些查询类型:

        SELECT country, state, city, COUNT(1) AS total        
        FROM `travel-sample`
        WHERE type = 'hotel' and country is not null
        GROUP BY country, state, city
        ORDER BY COUNT(1) DESC;

~90ms — Query plan of the query above

开发人员必须知道的关于Couchbase的10件事

~7ms — Same query as before but using a proper index

开发人员必须知道的关于Couchbase的10件事


6)基于角色的访问控制和X509证书

数据库对于任何恶意入侵者来说都是重磅炸弹,这就是为什么添加额外的安全层永远不会太多的原因。使用Couchbase,您可以使用X.509证书对客户进行身份验证,并通过基于角色的访问控制(RBAC)限制其访问:

开发人员必须知道的关于Couchbase的10件事


您还可以通过N1QL授予权限。让我们看看在bucket some_bucket中为用户denis授予SELECT权限是什么样子的:

GRANT ROLE query_select(some_bucket) TO denis;


7) Field Encryption

rest加密是最基本的安全形式之一,您可以使用Couchbase的Java加密轻松加密/解密字段:

        public static class Person {        
            @Id
            public String id;
        
            @EncryptedField(provider = "AES")
            public String password;
        
            //The rest will be transported and stored unencrypted
            public String firstName;
            public String lastName;
            public String userName;
            public int age;
          }

8) Reactive SDK

我们还提供了一个reactive SDK,这在数据库提供程序的大部分中并不容易找到。这主要是由于我们的SDK本身是被动实现的。


reactive编程对于性能和资源优化非常重要。如果您还不熟悉这个概念,我强烈推荐这篇文章,它让您快速了解为什么要考虑在持久性层中使用reactive编程。

9) 通过SDK进行“微调”

在Couchbase中,我们试图授权开发人员在文档级别上对其性能进行微调,这样开发人员就可以根据具体情况决定每种场景的最佳折衷方案。


例如,让我们看看Couchbase如何存储数据。默认情况下,一旦服务器确认应该存储新文档,它就会将响应发送回客户机,表示您的“请求已成功接收”,然后异步地存储和复制文档。


这种方法非常有利于提高速度,但如果服务器在文档仍在服务器内存中时崩溃,那么丢失数据的可能性很小。如果您想避免这种情况,您可以通过SDK指定,只有在文件复制或存储在磁盘上之后,您才希望收到确认:

movieRepository.getCouchbaseOperations().save(movie, PersistTo.ONE, ReplicateTo.NONE);
//or
movieRepository.getCouchbaseOperations().save(movie, PersistTo.ONE, ReplicateTo.TWO);
...
movieRepository.getCouchbaseOperations().save(movie, PersistTo.NONE, ReplicateTo.ONE);

为什么要允许这样的事情发生?因为如果你能承受服务器崩溃时丢失数据的小概率,你就能显著提高性能。这不是一个孤注一掷的决定,因为您可以决定系统的哪些部分值得冒这样的风险。


您还可以对查询执行类似的操作。在这种情况下,如果您希望等待索引/视图根据最近的更改进行更新,或者您是否愿意返回您的文档的最新版本:

//You can use ScanConsistency.REQUEST_PLUS, ScanConsistency.NOT_BOUNDED or ScanConsistency.STATEMENT_PLUS
N1qlParams params = N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS).adhoc(true);
ParameterizedN1qlQuery query = N1qlQuery.parameterized(queryString, JsonObject.create(), params);
resourceRepository.getCouchbaseOperations().getCouchbaseBucket().query(query);

我们的SDK中还有一些其他特性也可以进行优化,所有这些小的决定都可以显著地提高您的性能。

10) 响应时间可观测性

我在之前的博客文章中已经提到了这一项,但我认为它值得再次提及。从5.5版开始,我们引入了一种称为响应时间可观性的新功能,它将为系统开发人员提供一种非常简单的方法来观察相对于(可调的)阈值的响应时间。


这个特性使用了opentracking格式,它记录慢的请求,然后在每个时间间隔之后记录关于它的详细信息,因此您可以很容易地识别性能较差的操作。

Apr 04, 2018 9:42:57 AM com.couchbase.client.core.tracing.ThresholdLogReporter logOverThreshold
WARNING: Operations over threshold: [ {
  "top" : [ {
    "server_us" : 8,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "get:0x6",
    "dispatch_us" : 315,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 576
  }, {
    "server_us" : 8,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "get:0x5",
    "dispatch_us" : 319,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 599
  }, {
    "server_us" : 8,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "get:0x4",
    "dispatch_us" : 332,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 632
  }, {
    "server_us" : 11,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "get:0x3",
    "dispatch_us" : 392,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 762
  }, {
    "server_us" : 23,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "get:0x1",
    "decode_us" : 9579,
    "dispatch_us" : 947,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 16533
  }, {
    "server_us" : 56,
    "encode_us" : 12296,
    "local_id" : "41837B87B9B1C5D1/000000004746B9AA",
    "local_address" : "127.0.0.1:55011",
    "operation_id" : "upsert:0x2",
    "dispatch_us" : 1280,
    "remote_address" : "127.0.0.1:11210",
    "total_us" : 20935
  } ],
  "service" : "kv",
  "count" : 6
} ]

默认情况下,响应时间可见性是打开的,我们已经定义了一组阈值,以避免记录健康的请求。如果希望突破集群的限制,甚至可以手动设置更小的阈值。你可以多读一些。


请关注公众号:程序你好
0

精彩评论

暂无评论...
验证码 换一张
取 消