分类 技术 下的文章

虽然有些人认为区块链是一个早晚会出现问题的解决方案,但是毫无疑问,这个创新技术是一个计算机技术上的奇迹。那么,究竟什么是区块链呢?

区块链

比特币 Bitcoin 或其它加密货币按时间顺序公开地记录交易的数字账本。

更通俗的说,它是一个公开的数据库,新的数据存储在被称之为 区块 block 的容器中,并被添加到一个不可变的 chain 中(因此被称为 区块链 blockchain ),之前添加的数据也在该链中。对于比特币或其它加密货币来说,这些数据就是一组组交易,不过,也可以是其它任何类型的数据。

区块链技术带来了全新的、完全数字化的货币,如比特币和 莱特币 Litecoin ,它们并不由任何中心机构管理。这给那些认为当今的银行系统是骗局并将最终走向失败的人带来了自由。区块链也革命性地改变了分布式计算的技术形式,如 以太坊 Ethereum 就引入了一种有趣的概念: 智能合约 smart contract

在这篇文章中,我将用不到 50 行的 Python 2.x 代码实现一个简单的区块链,我把它叫做 SnakeCoin。

不到 50 行代码的区块链

我们首先将从定义我们的区块是什么开始。在区块链中,每个区块随同时间戳及可选的索引一同存储。在 SnakeCoin 中,我们会存储这两者。为了确保整个区块链的完整性,每个区块都会有一个自识别的哈希值。如在比特币中,每个区块的哈希是该块的索引、时间戳、数据和前一个区块的哈希值等数据的加密哈希值。这里提及的“数据”可以是任何你想要的数据。

import hashlib as hasher

class Block:
  def __init__(self, index, timestamp, data, previous_hash):
    self.index = index
    self.timestamp = timestamp
    self.data = data
    self.previous_hash = previous_hash
    self.hash = self.hash_block()
  
  def hash_block(self):
    sha = hasher.sha256()
    sha.update(str(self.index) + 
               str(self.timestamp) + 
               str(self.data) + 
               str(self.previous_hash))
    return sha.hexdigest()

真棒,现在我们有了区块的结构了,不过我们需要创建的是一个区块链。我们需要把区块添加到一个实际的链中。如我们之前提到过的,每个区块都需要前一个区块的信息。但问题是,该区块链中的第一个区块在哪里?好吧,这个第一个区块,也称之为创世区块,是一个特别的区块。在很多情况下,它是手工添加的,或通过独特的逻辑添加的。

我们将创建一个函数来简单地返回一个创世区块解决这个问题。这个区块的索引为 0 ,其包含一些任意的数据值,其“前一哈希值”参数也是任意值。

import datetime as date

def create_genesis_block():
  # Manually construct a block with
  # index zero and arbitrary previous hash
  return Block(0, date.datetime.now(), "Genesis Block", "0")

现在我们可以创建创世区块了,我们需要一个函数来生成该区块链中的后继区块。该函数将获取链中的前一个区块作为参数,为要生成的区块创建数据,并用相应的数据返回新的区块。新的区块的哈希值来自于之前的区块,这样每个新的区块都提升了该区块链的完整性。如果我们不这样做,外部参与者就很容易“改变过去”,把我们的链替换为他们的新链了。这个哈希链起到了加密的证明作用,并有助于确保一旦一个区块被添加到链中,就不能被替换或移除。

def next_block(last_block):
  this_index = last_block.index + 1
  this_timestamp = date.datetime.now()
  this_data = "Hey! I'm block " + str(this_index)
  this_hash = last_block.hash
  return Block(this_index, this_timestamp, this_data, this_hash)

这就是主要的部分。

现在我们能创建自己的区块链了!在这里,这个区块链是一个简单的 Python 列表。其第一个的元素是我们的创世区块,我们会添加后继区块。因为 SnakeCoin 是一个极小的区块链,我们仅仅添加了 20 个区块。我们通过循环来完成它。

# Create the blockchain and add the genesis block
blockchain = [create_genesis_block()]
previous_block = blockchain[0]

# How many blocks should we add to the chain
# after the genesis block
num_of_blocks_to_add = 20

# Add blocks to the chain
for i in range(0, num_of_blocks_to_add):
  block_to_add = next_block(previous_block)
  blockchain.append(block_to_add)
  previous_block = block_to_add
  # Tell everyone about it!
  print "Block #{} has been added to the blockchain!".format(block_to_add.index)
  print "Hash: {}\n".format(block_to_add.hash) 

让我们看看我们的成果:

别担心,它将一直添加到 20 个区块

很好,我们的区块链可以工作了。如果你想要在主控台查看更多的信息,你可以编辑其完整的源代码并输出每个区块的时间戳或数据。

这就是 SnakeCoin 所具有的功能。要使 SnakeCoin 达到现今的产品级的区块链的高度,我们需要添加更多的功能,如服务器层,以在多台机器上跟踪链的改变,并通过工作量证明算法(POW)来限制给定时间周期内可以添加的区块数量。

如果你想了解更多技术细节,你可以在这里查看最初的比特币白皮书

让这个极小区块链稍微变大些

这个极小的区块链及其简单,自然也相对容易完成。但是因其简单也带来了一些缺陷。首先,SnakeCoin 仅能运行在单一的一台机器上,所以它相距分布式甚远,更别提去中心化了。其次,区块添加到区块链中的速度同在主机上创建一个 Python 对象并添加到列表中一样快。在我们的这个简单的区块链中,这不是问题,但是如果我们想让 SnakeCoin 成为一个实际的加密货币,我们就需要控制在给定时间内能创建的区块(和币)的数量。

从现在开始,SnakeCoin 中的“数据”将是交易数据,每个区块的“数据”字段都将是一些交易信息的列表。接着我们来定义“交易”。每个“交易”是一个 JSON 对象,其记录了币的发送者、接收者和转移的 SnakeCoin 数量。注:交易信息是 JSON 格式,原因我很快就会说明。

{
  "from": "71238uqirbfh894-random-public-key-a-alkjdflakjfewn204ij",
  "to": "93j4ivnqiopvh43-random-public-key-b-qjrgvnoeirbnferinfo",
  "amount": 3
}

现在我们知道了交易信息看起来的样子了,我们需要一个办法来将其加到我们的区块链网络中的一台计算机(称之为节点)中。要做这个事情,我们会创建一个简单的 HTTP 服务器,以便每个用户都可以让我们的节点知道发生了新的交易。节点可以接受 POST 请求,请求数据为如上的交易信息。这就是为什么交易信息是 JSON 格式的:我们需要它们可以放在请求信息中传递给服务器。

$ pip install flask # 首先安装 Web 服务器框架
from flask import Flask
from flask import request
node = Flask(__name__)

# Store the transactions that
# this node has in a list
this_nodes_transactions = []

@node.route('/txion', methods=['POST'])
def transaction():
  if request.method == 'POST':
    # On each new POST request,
    # we extract the transaction data
    new_txion = request.get_json()
    # Then we add the transaction to our list
    this_nodes_transactions.append(new_txion)
    # Because the transaction was successfully
    # submitted, we log it to our console
    print "New transaction"
    print "FROM: {}".format(new_txion['from'])
    print "TO: {}".format(new_txion['to'])
    print "AMOUNT: {}\n".format(new_txion['amount'])
    # Then we let the client know it worked out
    return "Transaction submission successful\n"

node.run()

真棒!现在我们有了一种保存用户彼此发送 SnakeCoin 的记录的方式。这就是为什么人们将区块链称之为公共的、分布式账本:所有的交易信息存储给所有人看,并被存储在该网络的每个节点上。

但是,有个问题:人们从哪里得到 SnakeCoin 呢?现在还没有办法得到,还没有一个称之为 SnakeCoin 这样的东西,因为我们还没有创建和分发任何一个币。要创建新的币,人们需要“挖”一个新的 SnakeCoin 区块。当他们成功地挖到了新区块,就会创建出一个新的 SnakeCoin ,并奖励给挖出该区块的人(矿工)。一旦挖矿的矿工将 SnakeCoin 发送给别人,这个币就流通起来了。

我们不想让挖新的 SnakeCoin 区块太容易,因为这将导致 SnakeCoin 太多了,其价值就变低了;同样,我们也不想让它变得太难,因为如果没有足够的币供每个人使用,它们对于我们来说就太昂贵了。为了控制挖新的 SnakeCoin 区块的难度,我们会实现一个 工作量证明 Proof-of-Work (PoW)算法。工作量证明基本上就是一个生成某个项目比较难,但是容易验证(其正确性)的算法。这个项目被称之为“证明”,听起来就像是它证明了计算机执行了特定的工作量。

在 SnakeCoin 中,我们创建了一个简单的 PoW 算法。要创建一个新区块,矿工的计算机需要递增一个数字,当该数字能被 9 (“SnakeCoin” 这个单词的字母数)整除时,这就是最后这个区块的证明数字,就会挖出一个新的 SnakeCoin 区块,而该矿工就会得到一个新的 SnakeCoin。

# ...blockchain
# ...Block class definition

miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"

def proof_of_work(last_proof):
  # Create a variable that we will use to find
  # our next proof of work
  incrementor = last_proof + 1
  # Keep incrementing the incrementor until
  # it's equal to a number divisible by 9
  # and the proof of work of the previous
  # block in the chain
  while not (incrementor % 9 == 0 and incrementor % last_proof == 0):
    incrementor += 1
  # Once that number is found,
  # we can return it as a proof
  # of our work
  return incrementor

@node.route('/mine', methods = ['GET'])
def mine():
  # Get the last proof of work
  last_block = blockchain[len(blockchain) - 1]
  last_proof = last_block.data['proof-of-work']
  # Find the proof of work for
  # the current block being mined
  # Note: The program will hang here until a new
  #       proof of work is found
  proof = proof_of_work(last_proof)
  # Once we find a valid proof of work,
  # we know we can mine a block so 
  # we reward the miner by adding a transaction
  this_nodes_transactions.append(
    { "from": "network", "to": miner_address, "amount": 1 }
  )
  # Now we can gather the data needed
  # to create the new block
  new_block_data = {
    "proof-of-work": proof,
    "transactions": list(this_nodes_transactions)
  }
  new_block_index = last_block.index + 1
  new_block_timestamp = this_timestamp = date.datetime.now()
  last_block_hash = last_block.hash
  # Empty transaction list
  this_nodes_transactions[:] = []
  # Now create the
  # new block!
  mined_block = Block(
    new_block_index,
    new_block_timestamp,
    new_block_data,
    last_block_hash
  )
  blockchain.append(mined_block)
  # Let the client know we mined a block
  return json.dumps({
      "index": new_block_index,
      "timestamp": str(new_block_timestamp),
      "data": new_block_data,
      "hash": last_block_hash
  }) + "\n"

现在,我们能控制特定的时间段内挖到的区块数量,并且我们给了网络中的人新的币,让他们彼此发送。但是如我们说的,我们只是在一台计算机上做的。如果区块链是去中心化的,我们怎样才能确保每个节点都有相同的链呢?要做到这一点,我们会使每个节点都广播其(保存的)链的版本,并允许它们接受其它节点的链。然后,每个节点会校验其它节点的链,以便网络中每个节点都能够达成最终的链的共识。这称之为 共识算法 consensus algorithm

我们的共识算法很简单:如果一个节点的链与其它的节点的不同(例如有冲突),那么最长的链保留,更短的链会被删除。如果我们网络上的链没有了冲突,那么就可以继续了。

@node.route('/blocks', methods=['GET'])
def get_blocks():
  chain_to_send = blockchain
  # Convert our blocks into dictionaries
  # so we can send them as json objects later
  for block in chain_to_send:
    block_index = str(block.index)
    block_timestamp = str(block.timestamp)
    block_data = str(block.data)
    block_hash = block.hash
    block = {
      "index": block_index,
      "timestamp": block_timestamp,
      "data": block_data,
      "hash": block_hash
    }
  # Send our chain to whomever requested it
  chain_to_send = json.dumps(chain_to_send)
  return chain_to_send

def find_new_chains():
  # Get the blockchains of every
  # other node
  other_chains = []
  for node_url in peer_nodes:
    # Get their chains using a GET request
    block = requests.get(node_url + "/blocks").content
    # Convert the JSON object to a Python dictionary
    block = json.loads(block)
    # Add it to our list
    other_chains.append(block)
  return other_chains

def consensus():
  # Get the blocks from other nodes
  other_chains = find_new_chains()
  # If our chain isn't longest,
  # then we store the longest chain
  longest_chain = blockchain
  for chain in other_chains:
    if len(longest_chain) < len(chain):
      longest_chain = chain
  # If the longest chain wasn't ours,
  # then we set our chain to the longest
  blockchain = longest_chain

我们差不多就要完成了。在运行了完整的 SnakeCoin 服务器代码之后,在你的终端可以运行如下代码。(假设你已经安装了 cCUL)。

1、创建交易

curl "localhost:5000/txion" \  
     -H "Content-Type: application/json" \  
     -d '{"from": "akjflw", "to":"fjlakdj", "amount": 3}'

2、挖一个新区块

curl localhost:5000/mine

3、 查看结果。从客户端窗口,我们可以看到。

对代码做下美化处理,我们看到挖矿后我们得到的新区块的信息:

{  
  "index": 2,  
  "data": {  
    "transactions": [  
      {  
        "to": "fjlakdj",  
        "amount": 3,  
        "from": "akjflw"  
      },  
      {  
        "to": "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi",  
        "amount": 1,  
        "from": "network"  
      }  
    ],  
    "proof-of-work": 36  
  },  
  "hash": "151edd3ef6af2e7eb8272245cb8ea91b4ecfc3e60af22d8518ef0bba8b4a6b18",  
  "timestamp": "2017-07-23 11:23:10.140996"  
}

大功告成!现在 SnakeCoin 可以运行在多个机器上,从而创建了一个网络,而且真实的 SnakeCoin 也能被挖到了。

你可以根据你的喜好去修改 SnakeCoin 服务器代码,并问各种问题了。

在下一篇(LCTT 译注:截止至本文翻译,作者还没有写出下一篇),我们将讨论创建一个 SnakeCoin 钱包,这样用户就可以发送、接收和存储他们的 SnakeCoin 了。

 title=

学习使用 Seahorse GUI 工具去管理 PGP 和 SSH 密钥。

安全即内心的平静。毕竟,安全是许多用户迁移到 Linux 的最大理由。但是为什么要止步于仅仅采用该平台,你还可以采用多种方法和技术去确保你的桌面或者服务器系统的安全。

其中一项技术涉及到密钥 —— 用在 PGP 和 SSH 中。PGP 密钥允许你去加密和解密电子邮件和文件,而 SSH 密钥允许你使用一个额外的安全层去登入服务器。

当然,你可以通过命令行接口(CLI)来管理这些密钥,但是,如果你使用一个华丽的 GUI 桌面环境呢?经验丰富的 Linux 用户可能对于脱离命令行来工作感到很不适应,但是,并不是所有用户都具备与他们相同的技术和水平,因此,使用 GUI 吧!

在本文中,我将带你探索如何使用 Seahorse GUI 工具来管理 PGP 和 SSH 密钥。Seahorse 有非常强大的功能,它可以:

  • 加密/解密/签名文件和文本。
  • 管理你的密钥和密钥对。
  • 同步你的密钥和密钥对到远程密钥服务器。
  • 签名和发布密钥。
  • 缓存你的密码。
  • 备份密钥和密钥对。
  • 在任何一个 GDK 支持的格式中添加一个图像作为一个 OpenPGP photo ID。
  • 创建、配置、和缓存 SSH 密钥。

对于那些不了解 Seahorse 的人来说,它是一个管理 GNOME 钥匙环中的加密密钥和密码的 GNOME 应用程序。不用担心,Seahorse 可以安装在许多的桌面环境上。并且由于 Seahorse 可以在标准的仓库中找到,你可以打开你的桌面应用商店(比如,Ubuntu Software 或者 Elementary OS AppCenter)去安装它。你可以在你的发行版的应用商店中点击去安装它。安装完成后,你就可以去使用这个很方便的工具了。

我们开始去使用它吧。

PGP 密钥

我们需要做的第一件事情就是生成一个新的 PGP 密钥。正如前面所述,PGP 密钥可以用于加密电子邮件(通过一些工具,像 ThunderbirdEnigmail 或者使用 Evolution 内置的加密功能)。PGP 密钥也可以用于加密文件。任何人都可以使用你的公钥加密电子邮件和文件发给你(LCTT 译注:原文此处“加密”误作“解密”)。没有 PGP 密钥是做不到的。

使用 Seahorse 创建一个新的 PGP 密钥对是非常简单的。以下是操作步骤:

  1. 打开 Seahorse 应用程序
  2. 在主面板的左上角点击 “+” 按钮
  3. 选择 “ PGP 密钥 PGP Key ”(如图 1 )
  4. 点击 “ 继续 Continue
  5. 当提示时,输入完整的名字和电子邮件地址
  6. 点击 “ 创建 Create

 title=

图 1:使用 Seahorse 创建一个 PGP 密钥。

在创建你的 PGP 密钥期间,你可以点击 “ 高级密钥选项 Advanced key options ” 展开选项部分,在那里你可以为密钥添加注释信息、加密类型、密钥长度、以及过期时间(如图 2)。

 title=

图 2:PGP 密钥高级选项

增加注释部分可以很方便帮你记住密钥的用途(或者其它的信息)。

要使用你创建的 PGP,可在密钥列表中双击它。在结果窗口中,点击 “ 名字 Names ” 和 “ 签名 Signatures ” 选项卡。在这个窗口中,你可以签名你的密钥(表示你信任这个密钥)。点击 “ 签名 Sign ” 按钮然后(在结果窗口中)指出 “ 你是如何仔细的检查这个密钥的? how carefully you’ve checked this key? ” 和 “ 其他人将如何看到该签名 how others will see the signature ”(如图 3)。

 title=

图 3:签名一个密钥表示信任级别。

当你处理其它人的密钥时,密钥签名是非常重要的,因为一个签名的密钥将确保你的系统(和你)做了这项签名工作并且完全信任这个重要的密钥。

谈到导入的密钥,Seahorse 可以允许你很容易地去导入其他人的公钥文件(这个文件以 .asc 为后缀)。你的系统上有其他人的公钥,意味着你可以加密发送给他们的电子邮件和文件(LCTT 译注:原文将“加密”误作“解密”)。然而,Seahorse 在很长的一段时间内都存在一个 已知的 bug。这个问题是,Seahorse 导入使用 GPG 版本 1,但是显示的是 GPG 版本 2。这意味着,在这个存在了很长时间的 bug 被修复之前,导入公钥总是失败的。如果你想导入一个公钥文件到 Seahorse 中,你只能去使用命令行。因此,如果有人发送给你一个文件 olivia.asc,你想去导入到 Seahorse 中使用它,你将只能运行命令 gpg2 --import olivia.asc。那个密钥将出现在 GnuPG 密钥列表中。你可以打开该密钥,点击 “ 我信任签名 I trust signatures ” 按钮,然后在问题 “ 你是如何仔细地检查该密钥的? how carefully you’ve checked the key ” 中,点击 “ 签名这个密钥 Sign this key ” 按钮去签名。

SSH 密钥

现在我们来谈谈我认为 Seahorse 中最重要的一个方面 — SSH 密钥。Seahorse 不仅可以很容易地生成一个 SSH 密钥,而且它也可以很容易地将生成的密钥发送到服务器上,因此,你可以享受到 SSH 密钥验证的好处。下面是如何生成一个新的密钥以及如何导出它到一个远程服务器上。

  1. 打开 Seahorse 应用程序
  2. 点击 “+” 按钮
  3. 选择 “Secure Shell Key”
  4. 点击 “Continue”
  5. 提供一个密钥描述信息
  6. 点击 “Set Up” 去创建密钥
  7. 输入密钥的验证密钥
  8. 点击 OK
  9. 输入远程服务器地址和服务器上的登录名(如图 4)
  10. 输入远程用户的密码
  11. 点击 OK

 title=

图 4:上传一个 SSH 密钥到远程服务器。

新密钥将上传到远程服务器上以备使用。如果你的服务器已经设置为使用 SSH 密钥验证,那就一切就绪了。

需要注意的是,在创建一个 SSH 密钥期间,你可以点击 “ 高级密钥选项 Advanced key options ”去展开它,配置加密类型和密钥长度(如图 5)。

 title=

图 5:高级 SSH 密钥选项。

Linux 新手必备

任何 Linux 新手用户都可以很快熟悉使用 Seahorse。即便是它有缺陷,Seahorse 仍然是为你准备的一个极其方便的工具。有时候,你可能希望(或者需要)去加密或者解密一个电子邮件/文件,或者为使用 SSH 验证来管理 SSH 密钥。如果你想去这样做而不希望使用命令行,那么,Seahorse 将是非常适合你的工具。

通过来自 Linux 基金会和 edX 的 "Linux 入门" 免费课程学习更多 Linux 的知识。


via: https://www.linux.com/learn/intro-to-linux/2018/2/how-manage-pgp-and-ssh-keys-seahorse

作者:JACK WALLEN 译者:qhwdw 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

学习 Linux 中的 大内存页 hugepage 。理解什么是“大内存页”,如何进行配置,如何查看当前状态以及如何禁用它。

Huge Pages in Linux

本文中我们会详细介绍 大内存页 huge page ,让你能够回答:Linux 中的“大内存页”是什么?在 RHEL6、RHEL7、Ubuntu 等 Linux 中,如何启用/禁用“大内存页”?如何查看“大内存页”的当前值?

首先让我们从“大内存页”的基础知识开始讲起。

Linux 中的“大内存页”是个什么玩意?

“大内存页”有助于 Linux 系统进行虚拟内存管理。顾名思义,除了标准的 4KB 大小的页面外,它们还能帮助管理内存中的巨大的页面。使用“大内存页”,你最大可以定义 1GB 的页面大小。

在系统启动期间,你能用“大内存页”为应用程序预留一部分内存。这部分内存,即被“大内存页”占用的这些存储器永远不会被交换出内存。它会一直保留其中,除非你修改了配置。这会极大地提高像 Oracle 数据库这样的需要海量内存的应用程序的性能。

为什么使用“大内存页”?

在虚拟内存管理中,内核维护一个将虚拟内存地址映射到物理地址的表,对于每个页面操作,内核都需要加载相关的映射。如果你的内存页很小,那么你需要加载的页就会很多,导致内核会加载更多的映射表。而这会降低性能。

使用“大内存页”,意味着所需要的页变少了。从而大大减少由内核加载的映射表的数量。这提高了内核级别的性能最终有利于应用程序的性能。

简而言之,通过启用“大内存页”,系统具只需要处理较少的页面映射表,从而减少访问/维护它们的开销!

如何配置“大内存页”?

运行下面命令来查看当前“大内存页”的详细内容。

root@kerneltalks # grep Huge /proc/meminfo
AnonHugePages:         0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB

从上面输出可以看到,每个页的大小为 2MB(Hugepagesize),并且系统中目前有 0 个“大内存页”(HugePages_Total)。这里“大内存页”的大小可以从 2MB 增加到 1GB

运行下面的脚本可以知道系统当前需要多少个巨大页。该脚本取之于 Oracle。

#!/bin/bash
#
# hugepages_settings.sh
#
# Linux bash script to compute values for the
# recommended HugePages/HugeTLB configuration
#
# Note: This script does calculation for all shared memory
# segments available when the script is run, no matter it
# is an Oracle RDBMS shared memory segment or not.
# Check for the kernel version
KERN=`uname -r | awk -F. '{ printf("%d.%d\n",$1,$2); }'`
# Find out the HugePage size
HPG_SZ=`grep Hugepagesize /proc/meminfo | awk {'print $2'}`
# Start from 1 pages to be on the safe side and guarantee 1 free HugePage
NUM_PG=1
# Cumulative number of pages required to handle the running shared memory segments
for SEG_BYTES in `ipcs -m | awk {'print $5'} | grep "[0-9][0-9]*"`
do
   MIN_PG=`echo "$SEG_BYTES/($HPG_SZ*1024)" | bc -q`
   if [ $MIN_PG -gt 0 ]; then
      NUM_PG=`echo "$NUM_PG+$MIN_PG+1" | bc -q`
   fi
done
# Finish with results
case $KERN in
   '2.4') HUGETLB_POOL=`echo "$NUM_PG*$HPG_SZ/1024" | bc -q`;
          echo "Recommended setting: vm.hugetlb_pool = $HUGETLB_POOL" ;;
   '2.6' | '3.8' | '3.10' | '4.1' ) echo "Recommended setting: vm.nr_hugepages = $NUM_PG" ;;
    *) echo "Unrecognized kernel version $KERN. Exiting." ;;
esac
# End

将它以 hugepages_settings.sh 为名保存到 /tmp 中,然后运行之:

root@kerneltalks # sh /tmp/hugepages_settings.sh
Recommended setting: vm.nr_hugepages = 124

你的输出类似如上结果,只是数字会有一些出入。

这意味着,你系统需要 124 个每个 2MB 的“大内存页”!若你设置页面大小为 4MB,则结果就变成了 62。你明白了吧?

配置内核中的“大内存页”

本文最后一部分内容是配置上面提到的 内核参数 ,然后重新加载。将下面内容添加到 /etc/sysctl.conf 中,然后输入 sysctl -p 命令重新加载配置。

vm.nr_hugepages=126

注意我们这里多加了两个额外的页,因为我们希望在实际需要的页面数量之外多一些额外的空闲页。

现在,内核已经配置好了,但是要让应用能够使用这些“大内存页”还需要提高内存的使用阀值。新的内存阀值应该为 126 个页 x 每个页 2 MB = 252 MB,也就是 258048 KB。

你需要编辑 /etc/security/limits.conf 中的如下配置:

soft memlock 258048
hard memlock 258048

某些情况下,这些设置是在指定应用的文件中配置的,比如 Oracle DB 就是在 /etc/security/limits.d/99-grid-oracle-limits.conf 中配置的。

这就完成了!你可能还需要重启应用来让应用来使用这些新的巨大页。

(LCTT 译注:此外原文有误,“透明大内存页”和“大内存页”不同,而且,在 Redhat 系统中,“大内存页” 不是默认启用的,而“透明大内存页”是启用的。因此这个段落删除了。)


via: https://kerneltalks.com/services/what-is-huge-pages-in-linux/

作者:Shrikant Lavhate 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

简介:这是一份详细指南,我将会向你展示如何手动或通过浏览器轻松安装 GNOME Shell 扩展 Extension

在讨论 如何在 Ubuntu 17.10 上安装主题 一文时,我简要地提到了 GNOME Shell 扩展,它用来安装用户主题。今天,我们将详细介绍 Ubuntu 17.10 中的 GNOME Shell 扩展。

我可能会使用术语 GNOME 扩展而不是 GNOME Shell 扩展,但是这两者在这里具有相同的含义。

什么是 GNOME Shell 扩展?如何安装 GNOME Shell 扩展,以及如何管理和删除 GNOME Shell 扩展?我会一一解释所有的问题。

在此之前,如果你喜欢视频,我已经在 FOSS 的 YouTube 频道 上展示了所有的这些操作。我强烈建议你订阅它来获得更多有关 Linux 的视频。

什么是 GNOME Shell 扩展?

GNOME Shell 扩展 根本上来说是增强 GNOME 桌面功能的一小段代码。

把它看作是你的浏览器的一个附加组件。例如,你可以在浏览器中安装附加组件来禁用广告。这个附加组件是由第三方开发者开发的。虽然你的 Web 浏览器默认不提供此项功能,但安装此附加组件可增强你 Web 浏览器的功能。

同样, GNOME Shell 扩展就像那些可以安装在 GNOME 之上的第三方附加组件和插件。这些扩展程序是为执行特定任务而创建的,例如显示天气状况、网速等。大多数情况下,你可以在顶部面板中访问它们。

GNOME Shell 扩展显示天气信息

也有一些 GNOME 扩展在顶部面板上不可见,但它们仍然可以调整 GNOME 的行为。例如,有一个这样的扩展可以让鼠标中键来关闭应用程序。

安装 GNOME Shell 扩展

现在你知道了什么是 GNOME Shell 扩展,那么让我们来看看如何安装它吧。有三种方式可以使用 GNOME 扩展:

  • 使用来自 Ubuntu (或你的 Linux 发行版)的最小扩展集
  • 在 Web 浏览器中查找并安装扩展程序
  • 下载并手动安装扩展

在你学习如何使用 GNOME Shell 扩展之前,你应该安装 GNOME Tweak Tool。你可以在软件中心找到它,或者你可以使用以下命令:

sudo apt install gnome-tweak-tool

有时候,你需要知道你正在使用的 GNOME Shell 的版本,这有助于你确定扩展是否与系统兼容。你可以使用下面的命令来找到它:

gnome-shell --version

1. 使用 gnome-shell-extensions 包 [最简单最安全的方式]

Ubuntu(以及其他几个 Linux 发行版,如 Fedora )提供了一个包,这个包有最小集合的 GNOME 扩展。由于 Linux 发行版经过测试,所以你不必担心兼容性问题。

如果你不想费神,你只需获得这个包,你就可以安装 8-10 个 GNOME 扩展。

sudo apt install gnome-shell-extensions

你将需要重新启动系统(或者重新启动 GNOME Shell,我具体忘了是哪个)。之后,启动 GNOME Tweaks,你会发现一些扩展自动安装了,你只需切换按钮即可开始使用已安装的扩展程序。

Change GNOME Shell theme in Ubuntu 17.1

2. 从 Web 浏览器安装 GNOME Shell 扩展

GNOME 项目有一个专门用于扩展的网站,不干别的,你可以在这里找到并安装扩展,并管理它们,甚至不需要 GNOME Tweaks Tool。

但是为了安装 Web 浏览器扩展,你需要两件东西:浏览器附加组件和本地主机连接器。

步骤 1: 安装 浏览器附加组件

当你访问 GNOME Shell 扩展网站时,你会看到如下消息:

“要使用此站点控制 GNOME Shell 扩展,你必须安装由两部分组成的 GNOME Shell 集成:浏览器扩展和本地主机消息应用。”

Installing GNOME Shell Extensions

你只需在你的 Web 浏览器上点击建议的附加组件链接即可。你也可以从下面的链接安装它们:

步骤 2: 安装本地连接器

仅仅安装浏览器附加组件并没有帮助。你仍然会看到如下错误:

“尽管 GNOME Shell 集成扩展正在运行,但未检测到本地主机连接器。请参阅文档以获取有关安装连接器的信息。”

How to install GNOME Shell Extensions

这是因为你尚未安装主机连接器。要做到这一点,请使用以下命令:

sudo apt install chrome-gnome-shell

不要担心包名中的 “chrome” 前缀,它与 Chrome 无关,你无需再次安装 Firefox 或 Opera 的单独软件包。

步骤 3: 在 Web 浏览器中安装 GNOME Shell 扩展

一旦你完成了这两个要求,你就可以开始了。现在,你将看不到任何错误消息。

GNOME Shell Extension

一件好的做法是按照 GNOME Shell 版本对扩展进行排序,但这不是强制性的。这是因为开发人员是为其当前的 GNOME 版本创建的扩展。而在一年之内,会发布两个或更多 GNOME 发行版本,但开发人员没有时间(在新的 GNOME 版本上)测试或更新他/她的扩展。

因此,你不知道该扩展是否与你的系统兼容。尽管扩展已经存在很长一段时间了,但是有可能在最新的 GNOME Shell 版本中,它也能正常工作。同样它也有可能不工作。

你也可以去搜索扩展程序。假设你想要安装有关天气的扩展,只要搜索它并选择一个搜索结果即可。

当你访问扩展页面时,你会看到一个切换按钮。

Installing GNOME Shell Extension

点击它,你会被提示是否要安装这个扩展:

Install GNOME Shell Extensions via web browser

显然,直接安装就好。安装完成后,你会看到切换按钮已打开,旁边有一个设置选项。你也可以使用设置选项配置扩展,也可以禁用扩展。

Configuring installed GNOME Shell Extensions

你也可以在 GNOME Tweaks Tool 中配置通过 Web 浏览器安装的扩展:

GNOME Tweaks to handle GNOME Shell Extensions

你可以在 GNOME 网站中 已安装的扩展部分 下查看所有已安装的扩展。

Manage your installed GNOME Shell Extensions

使用 GNOME 扩展网站的一个主要优点是你可以查看扩展是否有可用的更新,你不会在 GNOME Tweaks 或系统更新中得到更新(和提示)。

3. 手动安装 GNOME Shell 扩展

你不需要始终在线才能安装 GNOME Shell 扩展,你可以下载文件并稍后安装,这样就不必使用互联网了。

去 GNOME 扩展网站下载最新版本的扩展。

Download GNOME Shell Extension

解压下载的文件,将该文件夹复制到 ~/.local/share/gnome-shell/extensions 目录。到主目录下并按 Ctrl+H 显示隐藏的文件夹,在这里找到 .local 文件夹,你可以找到你的路径,直至 extensions 目录。

一旦你将文件复制到正确的目录后,进入它并打开 metadata.json 文件,寻找 uuid 的值。

确保该扩展的文件夹名称与 metadata.json 中的 uuid 值相同。如果不相同,请将目录重命名为 uuid 的值。

Manually install GNOME Shell extension

差不多了!现在重新启动 GNOME Shell。 按 Alt+F2 并输入 r 重新启动 GNOME Shell。

Restart GNOME Shell

同样重新启动 GNOME Tweaks Tool。你现在应该可以在 Tweaks Tool 中看到手动安装的 GNOME 扩展,你可以在此处配置或启用新安装的扩展。

这就是安装 GNOME Shell 扩展你需要知道的所有内容。

移除 GNOME Shell 扩展

你可能想要删除一个已安装的 GNOME Shell 扩展,这是完全可以理解的。

如果你是通过 Web 浏览器安装的,你可以到 GNOME 网站的以安装的扩展部分 那移除它(如前面的图片所示)。

如果你是手动安装的,可以从 ~/.local/share/gnome-shell/extensions 目录中删除扩展文件来删除它。

特别提示:获得 GNOME Shell 扩展更新的通知

到目前为止,你已经意识到除了访问 GNOME 扩展网站之外,无法知道更新是否可用于 GNOME Shell 扩展。

幸运的是,有一个 GNOME Shell 扩展可以通知你是否有可用于已安装扩展的更新。你可以从下面的链接中获得它:

你如何管理 GNOME Shell 扩展?

我觉得很奇怪不能通过系统更新来更新扩展,就好像 GNOME Shell 扩展不是系统的一部分。

如果你正在寻找一些建议,请阅读这篇文章: 关于最佳 GNOME 扩展。同时,你可以分享有关 GNOME Shell 扩展的经验。你经常使用它们吗?如果是,哪些是你最喜欢的?


via: https://itsfoss.com/gnome-shell-extensions/

作者:Abhishek Prakash 译者:MjSeven 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

今天我将谈一下我这个博客是如何搭建的。在我们开始之前,我希望你熟悉使用 Github 并且可以搭建一个 Python 虚拟环境来进行开发。如果你不能做到这些,我推荐你去学习一下 Django Girls 教程,它包含以上和更多的内容。

这是一篇帮助你发布由 Github 托管的个人博客的教程。为此,你需要一个正常的 Github 用户账户 (而不是一个工程账户)。

你要做的第一件事是创建一个放置代码的 Github 仓库。如果你想要你的博客仅仅指向你的用户名 (比如 rsip22.github.io) 而不是一个子文件夹 (比如 rsip22.github.io/blog),你必须创建一个带有全名的仓库。

Github 截图,打开了创建新仓库的菜单,正在以 'rsip22.github.io' 名字创建一个新的仓库

我推荐你使用 README、用于 Python 的 .gitignore一个自由软件许可证 初始化你的仓库。如果你使用自由软件许可证,你仍然拥有这些代码,但是你使得其他人能从中受益,允许他们学习和复用它,并且更重要的是允许他们享有这些代码。

既然仓库已经创建好了,那我们就克隆到本机中将用来保存代码的文件夹下:

$ git clone https://github.com/YOUR_USERNAME/YOUR_USERNAME.github.io.git

并且切换到新的目录:

 $ cd YOUR_USERNAME.github.io

因为 Github Pages 偏好运行的方式是从 master 分支提供文件,你必须将你的源代码放到新的分支,防止 Pelican 产生的静态文件输出到 master 分支。为此,你必须创建一个名为 source 的分支。

$ git checkout -b source

用你的系统所安装的 Pyhton 3 创建该虚拟环境(virtualenv)。

在 GNU/Linux 系统中,命令可能如下:

$ python3 -m venv venv

或者像这样:

$ virtualenv --python=python3.5 venv

并且激活它:

$ source venv/bin/activate

在虚拟环境里,你需要安装 pelican 和它的依赖包。你也应该安装 ghp-import (来帮助我们发布到 Github 上)和 Markdown (为了使用 markdown 语法来写文章)。运行如下命令:

(venv)$ pip install pelican markdown ghp-import

一旦完成,你就可以使用 pelican-quickstart 开始创建你的博客了:

(venv)$ pelican-quickstart

这将会提示我们一系列的问题。在回答它们之前,请看一下如下我的答案:

> Where do you want to create your new web site? [.] ./
> What will be the title of this web site? Renata's blog
> Who will be the author of this web site? Renata
> What will be the default language of this web site? [pt] en
> Do you want to specify a URL prefix? e.g., http://example.com (Y/n) n
> Do you want to enable article pagination? (Y/n) y
> How many articles per page do you want? [10] 10
> What is your time zone? [Europe/Paris] America/Sao_Paulo
> Do you want to generate a Fabfile/Makefile to automate generation and publishing? (Y/n) Y **# PAY ATTENTION TO THIS!**
> Do you want an auto-reload & simpleHTTP script to assist with theme and site development? (Y/n) n
> Do you want to upload your website using FTP? (y/N) n
> Do you want to upload your website using SSH? (y/N) n
> Do you want to upload your website using Dropbox? (y/N) n
> Do you want to upload your website using S3? (y/N) n
> Do you want to upload your website using Rackspace Cloud Files? (y/N) n
> Do you want to upload your website using GitHub Pages? (y/N) y
> Is this your personal page (username.github.io)? (y/N) y
 Done. Your new project is available at /home/username/YOUR_USERNAME.github.io

关于时区,应该指定为 TZ 时区(这里是全部列表: tz 数据库时区列表)。

现在,继续往下走并开始创建你的第一篇博文!你可能想在你喜爱的代码编辑器里打开工程目录并且找到里面的 content 文件夹。然后创建一个新文件,它可以被命名为 my-first-post.md (别担心,这只是为了测试,以后你可以改变它)。在文章内容之前,应该以元数据开始,这些元数据标识标题、日期、目录及更多,像下面这样:

.lang="markdown" # DON'T COPY this line, it exists just for highlighting purposes

Title: My first post
Date: 2017-11-26 10:01
Modified: 2017-11-27 12:30
Category: misc
Tags: first, misc
Slug: My-first-post
Authors: Your name
Summary: What does your post talk about? Write here.

This is the *first post* from my Pelican blog. **YAY!**

让我们看看它长什么样?

进入终端,产生静态文件并且启动服务器。要这么做,使用下面命令:

(venv)$ make html && make serve

当这条命令正在运行,你应该可以在你喜爱的 web 浏览器地址栏中键入 localhost:8000 来访问它。

博客主页的截图。它有一个带有 Renata's blog 标题的头部,第一篇博文在左边,文章的信息在右边,链接和社交在底部

相当简洁,对吧?

现在,如果你想在文章中放一张图片,该怎么做呢?好,首先你在放置文章的内容目录里创建一个目录。为了引用简单,我们将这个目录命名为 image。现在你必须让 Pelican 使用它。找到 pelicanconf.py 文件,这个文件是你配置系统的地方,并且添加一个包含你的图片目录的变量:

.lang="python" # DON'T COPY this line, it exists just for highlighting purposes

STATIC_PATHS = ['images']

保存它。打开文章并且以如下方式添加图片:

.lang="markdown" # DON'T COPY this line, it exists just for highlighting purposes

![Write here a good description for people who can't see the image]({filename}/images/IMAGE_NAME.jpg)

你可以在终端中随时按下 CTRL+C 来中断服务器。但是你应该再次启动它并检查图片是否正确。你能记住怎么样做吗?

(venv)$ make html && make serve

在你代码完工之前的最后一步:你应该确保任何人都可以使用 ATOM 或 RSS 流来读你的文章。找到 pelicanconf.py 文件,这个文件是你配置系统的地方,并且编辑关于 RSS 流产生的部分:

.lang="python" # DON'T COPY this line, it exists just for highlighting purposes

FEED_ALL_ATOM = 'feeds/all.atom.xml'
FEED_ALL_RSS = 'feeds/all.rss.xml'
AUTHOR_FEED_RSS = 'feeds/%s.rss.xml'
RSS_FEED_SUMMARY_ONLY = False

保存所有,这样你才可以将代码上传到 Github 上。你可以通过添加所有文件,使用一个信息(“first commit”)来提交它,并且使用 git push。你将会被问起你的 Github 登录名和密码。

$ git add -A && git commit -a -m 'first commit' && git push --all

还有...记住在最开始的时候,我给你说的怎样防止 Pelican 产生的静态文件输出 master 分支吗。现在对你来说是时候产生它们了:

$ make github

你将会被再次问及 Github 登录名和密码。好了!你的新博客应该创建在 https://YOUR_USERNAME.github.io

如果你在过程中任何一步遇到一个错误,请重新读一下这篇手册,尝试并看看你是否能发现错误发生的部分,因为这是调试的第一步。有时甚至一些简单的东西比如一个错字或者 Python 中错误的缩进都可以给我们带来麻烦。说出来并向网上或你的社区求助。

对于如何使用 Markdown 来写文章,你可以读一下 Daring Fireball Markdown 指南

为了获取其它主题,我建议你访问 Pelican 主题

这篇文章改编自 Adrien Leger 的使用一个 Bottstrap3 主题来搭建由 Github 托管的 Pelican 博客


via: https://rsip22.github.io/blog/create-a-blog-with-pelican-and-github-pages.html

作者:rsip22 译者:liuxinyu123 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我是一名新的 Vim 编辑器用户。我用它编写 Python 代码。有没有办法在 vim 中查看 Python 文档而无需访问互联网?假设我的光标在 Python 的 print 关键字下,然后按下 F1,我想查看关键字 print 的帮助。如何在 vim 中显示 python help() ?如何在不离开 vim 的情况下调用 pydoc3/pydoc 寻求帮助?

pydocpydoc3 命令可以根据 Python 关键字、主题、函数、模块或包的名称显示文本文档,或在模块内或包中的模块对类或函数的引用。你可以从 Vim 中调用 pydoc。让我们看看如何在 Vim 编辑器中使用 pydoc 访问 Python 文档。

使用 pydoc 访问 python 帮助

语法是:

pydoc keyword
pydoc3 keyword
pydoc len
pydoc print

编辑你的 ~/.vimrc

$ vim ~/.vimrc

pydoc3 添加以下配置(python v3.x 文档)。在正常模式下创建 H 键的映射:

nnoremap <buffer> H :<C-u>execute "!pydoc3 " . expand("<cword>")<CR>

保存并关闭文件。打开 Vim 编辑器:

$ vim file.py

写一些代码:

#!/usr/bin/python3
x=5
y=10
z=x+y
print(z)
print("Hello world")

将光标置于 Python 关键字 print 的下方,然后按下 Shift,然后按 H。你将看到下面的输出:

Access Python Help Within Vim

按 H 查看 Python 关键字 print 的帮助

如何在使用 Vim 时查看 python 帮助

jedi-vim 是一个绑定自动补全库 Jed 的 Vim 插件。它可以做很多事情,包括当你按下 Shift 后跟 K (即按大写 K) 就显示关键字的帮助。

如何在 Linux 或类 Unix 系统上安装 jedi-vim

使用 pathogenvim-plugVundle 安装 jedi-vim。我使用的是 vim-plug。在 ~/.vimrc 中添加以下行:

Plug 'davidhalter/jedi-vim'

保存并关闭文件。启动 Vim 并输入:

PlugInstall

在 Arch Linux 上,你还可以使用 pacman 命令从官方仓库中的 vim-jedi 安装 jedi-vim:

$ sudo pacman -S vim-jedi

它也可以在 Debian(比如 8)和 Ubuntu( 比如 14.04)上使用 apt-get command/apt-get command 安装 vim-python-jedi:

$ sudo apt install vim-python-jedi

在 Fedora Linux 上,它可以用 dnf 安装 vim-jedi:

$ sudo dnf install vim-jedi

Jedi 默认是自动初始化的。所以你不需要进一步的配置。要查看 Documentation/Pydoc,请按 K。它将弹出帮助窗口:

How to view python help when using vim

关于作者

作者是 nixCraft 的创建者,也是经验丰富的系统管理员和 Linux 操作系统/Unix shell 脚本的培训师。他曾与全球客户以及 IT、教育、国防和太空研究以及非营利部门等多个行业合作。在 TwitterFacebookGoogle + 上关注他。


via: https://www.cyberciti.biz/faq/how-to-access-view-python-help-when-using-vim/

作者:Vivek Gite 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出